diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/README.md b/README.md index e9d1205..f05dbc0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ # xit-ntri 세외수입 개별시스템 연계 API + + +### 빌드 방법 +jar 파일로 빌드 하기 +* 커맨드 이용 +```shell +gradle clean build -Pprofile=prod +``` +* IntelliJ 이용 +![img.png](img.png) + +### 빌드 파일 경로 +```text +~/build/libs +``` diff --git a/REF/deploy/check/README.md b/REF/deploy/check/README.md new file mode 100644 index 0000000..426e305 --- /dev/null +++ b/REF/deploy/check/README.md @@ -0,0 +1,46 @@ +# 시작하기 +*** +배포환경에 따라 WAS 및 JDK 버전이 각기 다르며 +이로인해 발생 할 수 있는 각종 오류들에 대한 원인을 파악하는데 있어 +datasource 접속가능여부 및 기타 정보를 확인할 수 있는 jsp 파일을 제공 한다. + + +### 버전관리 +|버전|작성일|작성자|내용| +|---|---|---|---| +|v0.1|2022.12.29|박민규|최초작성| + + +## 1. 배포하기 +1. [**Tomcat 다운로드**](https://tomcat.apache.org/) + * 원하는 버전의 zip 파일 다운로드 +2. **다운로드 파일 unzip** +3. **서버 기동하기** - *~/bin/startup.bat* 파일 실행 + **\[ JDK 오류발생 시 처리방법 \]** + + *~/bin* 경로에 **setenv.bat 파일 생성** + + setenv.bat 파일에 **JAVA_HOME 작성** + + set JAVA_HOME=[JDK 설치 경로] + + ex) set JAVA_HOME=C:\XIT\java\corretto-11.0.15 +4. **정상기동 여부 확인** - http://localhost:8080 으로 접속 + + 고양이 그림이 있는 Apache Tomcat 화면이 뜨면 성공 +5. *~/webapps* 경로에 **"check" 디렉토리 복사** +6. **서버 재기동** - ~/bin/shutdown.bat & ~/bin/startup.bat + + +## 2. 테스트 +1. 페이지 호출 + + http://localhost:8080/[파일명] //부록-파일 설명 참고 + + ex) http://localhost:8080/javaenv.jsp + +※ *DB 접속 테스트(datasource.jsp) 시*에는 ~/lib 경로에 *jdbc 라이브러리 파일(.jar)을 추가*해야 한다. + +# 부록 +*** +### 파일 설명 +|File Name|Description| +|---|---| +|datasource.jsp|DB 접속 테스트| +|fontinfo.jsp|현재 플랫폼에서 사용가능한 폰트 목록 확인| +|hostname.jsp|호스트명 확인| +|javaenv.jsp|java 시스템 등록정보| +|urlcheck.jsp|URL 호출 테스트| diff --git a/REF/deploy/check/datasource.jsp b/REF/deploy/check/datasource.jsp new file mode 100644 index 0000000..ce56012 --- /dev/null +++ b/REF/deploy/check/datasource.jsp @@ -0,0 +1,293 @@ +<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> +<%@ page import="java.sql.*, javax.sql.*, javax.naming.*" %> +<% + request.setCharacterEncoding("UTF-8"); //2020.09.25. 박민규- 캐릭터셋 설정 + + String uri = request.getRequestURI(); + + String type = request.getParameter("type"); + String dsNm = request.getParameter("dsNm"); + + String driver = request.getParameter("driver"); + String url = request.getParameter("url"); + String user = request.getParameter("user"); + String password = request.getParameter("password"); + + String sql = request.getParameter("sql"); + + if( type == null || type.equalsIgnoreCase("null") ) type = ""; + if( dsNm == null || dsNm.equalsIgnoreCase("null") ) dsNm = ""; + + if( driver == null || driver.equalsIgnoreCase("null") ) driver = ""; + if( url == null || url.equalsIgnoreCase("null") ) url = ""; + if( user == null || user.equalsIgnoreCase("null") ) user = ""; + if( password == null || password.equalsIgnoreCase("null") ) password = ""; + + if( sql == null || sql.equalsIgnoreCase("null") ) sql = ""; + + String msg = ""; + + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + +%> + + + + +DataSource 확인 + + + + +

Check DataSource

+
+ + + + + + + + + + + + + + + + + + + +
WAS 유형 + + DataSource +
+ +
+
Driver + + URL + +
User + + Password + +
+ + + + +
+ +
+<% + if( type.equals("lookup") || type.equals("nonlookup") || type.equals("direct") ) { + + try { + + if( type.equals("lookup") ) { //lookup type (Tomcat, resin, Jrun ...) + + Context ctx = new InitialContext(); + Context env = (Context)ctx.lookup("java:comp/env"); + DataSource ds = (DataSource)env.lookup(dsNm); + conn = ds.getConnection(); + } + else if( type.equals("nonlookup") ) { //nonlookup type (Jeus, WebLogic, WebSphere ...) + + Context ctx = new InitialContext(); + DataSource ds = (DataSource)ctx.lookup(dsNm); + conn = ds.getConnection(); + } + else { //direct + + Class.forName(driver); + conn = DriverManager.getConnection(url, user, password); + } + + if( conn == null ) msg = "Connection Fail!!!"; + else msg = "Connection Success!!!"; + } + catch(Exception e) { + + msg = e.getMessage(); + } + finally { +%> + + + + + + + +
Result(<%= type %>)
<%= msg %>
+ +<% + if( conn != null ) { +%> +
+ + + + + + + +
SQL
+ +
+ + + + +
+ +
+ +<% + if( sql != null && !sql.equals("") ) { +%> + +<% + try { + + ps = conn.prepareStatement(sql); + rs = ps.executeQuery(); + + ResultSetMetaData rsmd = rs.getMetaData(); + int cnt = rsmd.getColumnCount(); + + out.println(""); + for(int i = 0; i <= cnt; i++) { + + if( i == 0 ) out.println(""); + else out.println(""); + } + + int row_cnt = 0; + while( rs.next() ) { + + out.println(""); + for(int i = 0; i <= cnt; i++) { + + if( i == 0 ) out.println(""); + else out.println(""); + } + out.println(""); + } + + if( row_cnt == 0 ) { + + out.println(""); + } + } + catch(Exception ee) { + + out.println(""); + out.println(""); + } +%> + +
No" + rsmd.getColumnLabel(i) + "
" + ++row_cnt + "" + rs.getString(i) + "
조회 내역이 없습니다.
Error Message
" + ee.getMessage() + "
+ +<% + } + if( rs != null ) try{ rs.close(); rs = null; } catch (Exception ex) {} + if( ps != null ) try{ ps.close(); ps = null; } catch (Exception ex) {} + if( conn != null ) try { conn.close(); conn = null; } catch(Exception e) {} + } + } + } +%> +
+ + + diff --git a/REF/deploy/check/fontinfo.jsp b/REF/deploy/check/fontinfo.jsp new file mode 100644 index 0000000..a2d0aa7 --- /dev/null +++ b/REF/deploy/check/fontinfo.jsp @@ -0,0 +1,24 @@ +<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> +<%@ page import="java.awt.*" %> + + + + + +Font 정보 + + +<% + //System.setProperty("sun.java2d.fontpath", "font_location_path"); + // System.setProperty("java.awt.headless", "true"); + String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); + for (int i=0; i"); + } +%> + + diff --git a/REF/deploy/check/hostname.jsp b/REF/deploy/check/hostname.jsp new file mode 100644 index 0000000..8f8f46b --- /dev/null +++ b/REF/deploy/check/hostname.jsp @@ -0,0 +1,19 @@ +<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> +<%@ page import="java.net.*" %> + + + + + +Hostname 확인 + + + +

Hostname Check

+ + Hostname : [<%= InetAddress.getLocalHost().getHostName() %>]
+ AppPath : [<%= getServletContext().getRealPath("/") %>] + + diff --git a/REF/deploy/check/javaenv.jsp b/REF/deploy/check/javaenv.jsp new file mode 100644 index 0000000..7f2516d --- /dev/null +++ b/REF/deploy/check/javaenv.jsp @@ -0,0 +1,26 @@ +<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> + + + + +Java Environment 확인 + + +<% + java.util.Enumeration e = System.getProperties().propertyNames(); + while(e.hasMoreElements()) { + + String key = (String)e.nextElement(); + if( key.indexOf("class.path") != -1 || key.indexOf("loader") != -1 ) out.print("
  • " + key + " : " + System.getProperty(key) + "
  • "); + else out.print("
  • " + key + " : " + System.getProperty(key) + "
    "); + } +%> + + \ No newline at end of file diff --git a/REF/deploy/check/urlcheck.jsp b/REF/deploy/check/urlcheck.jsp new file mode 100644 index 0000000..cc7043e --- /dev/null +++ b/REF/deploy/check/urlcheck.jsp @@ -0,0 +1,134 @@ +<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> +<%@ page import="java.net.*, java.io.*" %> + +<% + String NL = System.getProperty("line.separator"); + + String sReqType = request.getParameter("req_type"); + String sUrl = request.getParameter("url"); + + if( sReqType == null || sReqType.equalsIgnoreCase("null") ) { + + sReqType = "GET"; + } + if( sUrl == null || sUrl.equalsIgnoreCase("null") ) { + + sUrl = ""; + } + + StringBuffer contents = new StringBuffer(); + + if( !sUrl.equals("") ) { + + try { + + URL url = new URL(sUrl); + contents.append(">> URL(" + sUrl + ") Connecting...").append(NL); + HttpURLConnection uc = (HttpURLConnection)url.openConnection(); + + uc.setDoOutput(true); + uc.setDoInput(true); + uc.setUseCaches(false); + uc.setRequestMethod(sReqType); + + StringBuffer sb = new StringBuffer(); + + InputStream is = uc.getInputStream(); + contents.append(">> Reading Contents...").append(NL); + + BufferedReader in = new BufferedReader(new InputStreamReader(is)); + + int buffSize = 1024 * 8; + char[] buff; + int insize = 0; + while ((insize = in.read(buff = new char[buffSize], 0, buffSize)) != -1) { + + sb.append((new String(buff, 0, insize))); + } + String receivestr = sb.toString().trim(); + + contents.append(">> Contents").append(NL); + contents.append("------------------------------------------").append(NL); + contents.append(sb.toString().trim()).append(NL); + contents.append("------------------------------------------").append(NL); + contents.append(">> End").append(NL); + } + catch(FileNotFoundException fnfe){ + + contents.append(">> FileNotFoundException").append(NL); + contents.append("------------------------------------------").append(NL); + contents.append(fnfe.getMessage()).append(NL); + contents.append("------------------------------------------").append(NL); + contents.append(">> End").append(NL); + fnfe.printStackTrace(); + } + catch(Exception e){ + + contents.append(">> Exception").append(NL); + contents.append("------------------------------------------").append(NL); + contents.append(e.getMessage()).append(NL); + contents.append("------------------------------------------").append(NL); + contents.append(">> End").append(NL); + e.printStackTrace(); + } + } + +%> + + + + +URL 확인 + + + + +

    Check URL

    +
    + + + + + + + + + +
    REQ TYPE + +
    URL + +
    + + + + +
    + +
    +
    + + Result
    + + + \ No newline at end of file diff --git a/REF/deploy/ntri/README.md b/REF/deploy/ntri/README.md new file mode 100644 index 0000000..c59868f --- /dev/null +++ b/REF/deploy/ntri/README.md @@ -0,0 +1,113 @@ +# 시작하기 +*** +세외수입개별시스템(Non-Tax Revenue Individual System) 은 \ +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며, \ +API 4종의 데이터는 세외수입시스템측에서 제공 한다. +* 출발지: 세외수입시스템 +* 목적지: 개별시스템(ntri) + + + +### 버전관리 +|버전|작성일|작성자|내용| +|---|---|---|---| +|v0.1|2022.12.20|박민규|최초작성| +|v0.2|2022.12.21|박민규|"2. SSL 인증서 발급" 내용 수정( 발급방식 변경: 스크립트 -> 실행파일(.bat) )| +|v0.2|2022.12.21|박민규|%NTRI_APP_HOME%/bin/setenv.bat 파일의 "DB/SSL설정" 수정VM옵션" 환경변수 추가| +|v0.3|2022.12.22|박민규|연계표준지침(v1.2.1) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json)| +|v0.3.1|2022.12.23|박민규|"1. 배포하기"에 NTRI_JAVA_HOME 설정에 대한 내용 추가 및 실행 환경 JDBC 내용추가| +|v0.3.2|2022.12.27|박민규|"부록-실행 환경"의 JDBC 수정(ojdbc8.jar -> ojdbc6.jar). 사유: 일부 서버에서 Java.sql.SQLRecoverableException 발생| +|v0.3.3|2022.12.27|박민규|문서내용 수정. "부록-실행 환경" `삭제`. "부록-구현 스펙" `추가`| +|v0.4|2022.12.27|박민규|연계표준지침(v1.2.1 -> v1.?.?) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json). reqVo 필드타입 수정(단건 -> 다건)| +|v0.4.1|2022.12.29|박민규|curl프로그램 변경 및 프로그램 위치 변경(%NTRI_APP_HOME% -> %NTRI_APP_HOME%/bin/test). "부록-디렉토리 구성"에서 내용 삭제| +|v0.5|2023.01.02|박민규|연계대상코드(linkTrgtCd) 설정 추가. (어플리케이션 수정 및 setenv.bat 환경변수 NTRI_APP_LINKTRGTCD 추가)| + + +## 1. 배포하기 +1. **원하는 경로에 ntri.zip 압축파일을 unzip** 한다. + * [원하는 경로]/ntri -> **%NTRI_APP_HOME%** +2. *%NTRI_APP_HOME%/bin/setenv.bat* 파일을 열어 **배포환경에 맞게 환경변수를 수정** 한다. + * NTRI_JAVA_HOME 및 SSL/DB 설정 등.. + **\[ NTRI_JAVA_HOME 설정 참고 \]** + * PC에 JDK가 설치(install)된 경우 + * JDK버전이 11 이상이면 -> %JAVA_HOME% 작성 + * JDK버전이 11 미만이면 -> [JDK11(Amazon Corretto) 다운로드(.zip)](https://docs.aws.amazon.com/ko_kr/corretto/latest/corretto-11-ug/downloads-list.html) 및 Unzip 한 path 작성 + * PC에 JDK가 미설치(no install)된 경우(unzip 또는 install 中 택1) + * [JDK11(Amazon Corretto) 다운로드(.zip)](https://docs.aws.amazon.com/ko_kr/corretto/latest/corretto-11-ug/downloads-list.html) 및 Unzip 한 path 작성 + * [JDK11(Amazon Corretto) 다운로드(.msi)](https://docs.aws.amazon.com/ko_kr/corretto/latest/corretto-11-ug/downloads-list.html) 및 Install 후 %JAVA_HOME% 작성 + + ※JDK 설치 확인 방법: cmd 창에서 `java -version` 입력 + ※JAVA_HOME 설정 확인 방법: 시스템 -> 정보 -> 고급 시스템 설정 -> 환경 변수(N)... -> 시스템 변수(S) +3. *%NTRI_APP_HOME%/bin/service-regist.bat* 파일을 **"관리자권한" 으로 실행** +4. *%NTRI_APP_HOME%/webapp* 디렉토리에 **"ntri-0.0.1-SNAPSHOT.jar" 파일 복사** +5. *%NTRI_APP_HOME%/bin/service-start.bat* 파일을 실행하여 "서비스 시작" + * 서비스 실행 오류가 발생할 경우 *%NTRI_APP_HOME%/logs/stderr.log* 내용 확인 +6. *%NTRI_APP_HOME%/bin/service-logprint.bat* 파일을 실행하여 "서비스 실시간 로그" 확인 + +## 2. SSL 인증서 발급 +1. [OpenSSL 다운로드](https://sourceforge.net/projects/openssl) + * openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip +2. 다운로드한 압축파일을 unzip 후 **OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 복사** +3. *%NTRI_APP_HOME%/ssl/bin* 디렉토리의 **"generate-ssl-cert-new.bat" 파일 실행** + **\[ 파일 설명 \]** + * 신규 발급: *generate-ssl-cert-new.bat* + * 인증서파일 `모두` 발급(key, csr, crt) + * 재발급: *generate-ssl-cert-refresh.bat* + * 인증서파일 `일부`만 발급(csr, crt) +4. *%NTRI_APP_HOME%/ssl/cert* 디렉토리에 **인증서파일(key,csr,crt) 이 생성**되었는지 **확인** + + +## 3. API 테스트 +1. **"~/bin/test"** 디렉토리로 이동 +2. 테스트 배치파일(.bat) 실행하여 API 호출 + * 일괄: *curl-all.bat* + * 부과취소: *curl-LevyCancel.bat* + * 부과결과: *curl-LevyResult.bat* + * 수납정보: *curl-RcivInfo.bat* + * 감액정보: *curl-RdcamtInfo.bat* + +# 부록 +*** +### 디렉토리 구성 +|Directory|Description| +|---|---| +|%NTRI_APP_HOME%/webapp|어플리케이션 jar 파일이 위치한 디렉토리| +|%NTRI_APP_HOME%/bin|서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리| +|%NTRI_APP_HOME%/bin/test|API 테스트 배치파일(.bat)이 위치한 디렉토리| +|%NTRI_APP_HOME%/bin/logs|어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)| +|%NTRI_APP_HOME%/logs|어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)| +|%NTRI_APP_HOME%/ssl/bin|SSL 인증서 신규/재발급을 위한 배치파일(.bat)이 위치한 디렉토리| +|%NTRI_APP_HOME%/ssl/cert|발급된 SSL 인증서가 저장되는 디렉토리| +|%NTRI_APP_HOME%/ssl/cert/backup|SSL 인증서 신규/재발급 시마다 발급된 인증서가 백업되는 디렉토리| + +### 파일 설명 +|File Name|Description| +|---|---| +|setenv.bat|`환경변수` 설정| +|service-regist.bat|서비스 `등록`| +|service-edit.bat|등록한 서비스정보 `수정`| +|service-delete.bat|등록한 서비스 `삭제`| +|service-start.bat|등록한 서비스 `실행`| +|service-stop.bat|등록한 서비스 `중지`| +|service-status.bat|등록한 서비스 실행 `상태` 확인| +|service-logprint.bat|등록한 서비스 `실시간 로그` 출력| +|startup.bat|서버 `기동`| +|shutdown.bat|서버 `종료`| +|logprint.bat|`실시간 로그` 출력| + +### 구현 스펙 ++ Back-End + + SpringBoot 2.7.5 + + Tomcat 9.0.68 + + JDK11 + + gradle + + JPA ++ DB + + Oracle 11g + + mariaDB 10.6.5 + + mysql ++ JDBC Libray + + ojdbc6.jar + + mariadb-java-client-2.7.5.jar + + mysql-connector-java-8.0.30.jar + \ No newline at end of file diff --git a/REF/deploy/ntri/README.v0.1.html b/REF/deploy/ntri/README.v0.1.html new file mode 100644 index 0000000..d803ac1 --- /dev/null +++ b/REF/deploy/ntri/README.v0.1.html @@ -0,0 +1,202 @@ + + + + + + README.md + + + +

    시작하기

    +
    +

    세외수입개별시스템(Non-Tax Revenue Individual System) 은
    +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며,
    +API 4종의 데이터는 세외수입시스템측에서 제공 한다.

    +
      +
    • 출발지: 세외수입시스템
    • +
    • 목적지: 개별시스템(ntri)
    • +
    +

    버전관리

    + + + + + + + + + + + + + + + + + +
    버전작성일작성자내용
    v0.12022.12.20박민규최초작성
    +

    1. 배포하기

    +
      +
    1. + 원하는 경로에 ntri.zip 압축파일을 unzip 한다.
    2. +
    3. + %NTRI_APP_HOME%/bin/setenv.bat 파일을 열어 배포환경에 맞게 환경변수를 수정 한다. +
      • NTRI_JAVA_HOME 및 SSL/DB 설정 등..
    4. +
    5. + %NTRI_APP_HOME%/bin/service-regist.bat 파일을 "관리자권한" 으로 실행
    6. +
    7. + %NTRI_APP_HOME%/webapp 디렉토리에 "ntri-0.0.1-SNAPSHOT.jar" 파일 복사
    8. +
    9. + %NTRI_APP_HOME%/bin/service-start.bat 파일을 실행하여 "서비스 시작" +
      • 서비스 실행 오류가 발생할 경우 %NTRI_APP_HOME%/logs/stderr.log 내용 확인
    10. +
    11. + %NTRI_APP_HOME%/bin/service-logprint.bat 파일을 실행하여 "서비스 실시간 로그" 확인
    12. +
    +

    2. SSL 인증서 발급

    +
      +
    1. OpenSSL 다운로드(https://sourceforge.net/projects/openssl) +
      • openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip
    2. +
    3. 다운로드한 압축파일을 unzip 후 OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 이동
    4. +
    5. + 관리자 권한으로 cmd창 열기
    6. +
    7. cd 커맨드로 C:\OpenSSL\bin 디렉토리로 이동
    8. +
    +
    +      cd C:\Openssl\bin
    +
    +    
    +
      +
    1. 인증서 발급 커맨드 실행
    2. +
    +
    +      openssl req -config ./openssl.cnf -x509 -sha256 -nodes -newkey rsa:2048 -keyout private.key -out public.pem -days 3650
    +	-> 커맨드 종료시까지 엔터키(Enter) 입력	
    +	
    +openssl pkcs12 -export -inKey private.key -in public.pem -name alias_name -out certificate.p12
    +	-> 인증서 패스워드 `xit5811807` 입력 
    +	※ openssl.cnf 관련 오류 발생 시 openssl.cnf 파일을 C:/OpenSSL 밑으로 복사
    +
    +    
    +
      +
    1. 생성된 certificate.p12 파일을 "%NTRI_APP_HOME%/ssl/cert" 디렉토리로 복사
    2. +
    +

    3. API 테스트

    +
      +
    1. + "~/bin/test" 디렉토리로 이동
    2. +
    3. 테스트 배치파일(.bat) 실행하여 API 호출 +
      • 일괄: curl-all.bat
      • 부과취소: curl-LevyCancel.bat
      • 부과결과: curl-LevyResult.bat
      • 수납정보: curl-RcivInfo.bat
      • 감액정보: curl-RdcamtInfo.bat
    4. +
    +

    부록

    +
    +

    디렉토리 구성

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectoryDescription
    %NTRI_APP_HOME%/webapp어플리케이션 jar 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/testAPI 테스트 배치파일(.bat) 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)
    %NTRI_APP_HOME%/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)
    %NTRI_APP_HOME%/sslSSL 인증 관련 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/curl-7.86.0_2-win64-mingwcurl 커맨드를 사용하기 위한 실행프로그램
    +

    파일 설명

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    File NameDescription
    setenv.bat + 환경변수 설정
    service-regist.bat서비스 등록
    service-edit.bat등록한 서비스정보 수정
    service-delete.bat등록한 서비스 삭제
    service-start.bat등록한 서비스 실행
    service-stop.bat등록한 서비스 중지
    service-status.bat등록한 서비스 실행 상태 확인
    service-logprint.bat등록한 서비스 실시간 로그 출력
    startup.bat서버 기동
    shutdown.bat서버 종료
    logprint.bat + 실시간 로그 출력
    +

    실행 환경

    +
      +
    • Java 버전: JDK11 이상
    • +
    • Tomcat 버전: Tomcat9 이상
    • +
    • JDBC: ojdbc8.jar
    • +
    + + diff --git a/REF/deploy/ntri/README.v0.2.html b/REF/deploy/ntri/README.v0.2.html new file mode 100644 index 0000000..221961c --- /dev/null +++ b/REF/deploy/ntri/README.v0.2.html @@ -0,0 +1,204 @@ + + + + + + README.md + + + +

    시작하기

    +
    +

    세외수입개별시스템(Non-Tax Revenue Individual System) 은
    +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며,
    +API 4종의 데이터는 세외수입시스템측에서 제공 한다.

    +
      +
    • 출발지: 세외수입시스템
    • +
    • 목적지: 개별시스템(ntri)
    • +
    +

    버전관리

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    버전작성일작성자내용
    v0.12022.12.20박민규최초작성
    v0.22022.12.21박민규"2. SSL 인증서 발급" 내용 수정( 발급방식 변경: 스크립트 -> 실행파일(.bat) )
    v0.22022.12.21박민규%NTRI_APP_HOME%/bin/setenv.bat 파일의 "DB/SSL설정" 수정VM옵션" 환경변수 추가
    +

    1. 배포하기

    +
      +
    1. + 원하는 경로에 ntri.zip 압축파일을 unzip 한다.
    2. +
    3. + %NTRI_APP_HOME%/bin/setenv.bat 파일을 열어 배포환경에 맞게 환경변수를 수정 한다. +
      • NTRI_JAVA_HOME 및 SSL/DB 설정 등..
    4. +
    5. + %NTRI_APP_HOME%/bin/service-regist.bat 파일을 "관리자권한" 으로 실행
    6. +
    7. + %NTRI_APP_HOME%/webapp 디렉토리에 "ntri-0.0.1-SNAPSHOT.jar" 파일 복사
    8. +
    9. + %NTRI_APP_HOME%/bin/service-start.bat 파일을 실행하여 "서비스 시작" +
      • 서비스 실행 오류가 발생할 경우 %NTRI_APP_HOME%/logs/stderr.log 내용 확인
    10. +
    11. + %NTRI_APP_HOME%/bin/service-logprint.bat 파일을 실행하여 "서비스 실시간 로그" 확인
    12. +
    +

    2. SSL 인증서 발급

    +
      +
    1. OpenSSL 다운로드(https://sourceforge.net/projects/openssl) +
      • openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip
    2. +
    3. 다운로드한 압축파일을 unzip 후 OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 복사
    4. +
    5. + %NTRI_APP_HOME%/ssl/bin 디렉토리의 "generate-ssl-cert-new.bat" 파일 실행
      [ 파일 설명 ]
      • 신규 발급: generate-ssl-cert-new.bat
        • 인증서파일 모두 발급(key, csr, crt)
      • 재발급: generate-ssl-cert-refresh.bat
        • 인증서파일 일부만 발급(csr, crt)
    6. +
    7. + %NTRI_APP_HOME%/ssl/cert 디렉토리에 인증서파일(key,csr,crt) 이 생성되었는지 확인
    8. +
    +

    3. API 테스트

    +
      +
    1. + "~/bin/test" 디렉토리로 이동
    2. +
    3. 테스트 배치파일(.bat) 실행하여 API 호출 +
      • 일괄: curl-all.bat
      • 부과취소: curl-LevyCancel.bat
      • 부과결과: curl-LevyResult.bat
      • 수납정보: curl-RcivInfo.bat
      • 감액정보: curl-RdcamtInfo.bat
    4. +
    +

    부록

    +
    +

    디렉토리 구성

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectoryDescription
    %NTRI_APP_HOME%/webapp어플리케이션 jar 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/testAPI 테스트 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)
    %NTRI_APP_HOME%/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)
    %NTRI_APP_HOME%/ssl/binSSL 인증서 신규/재발급을 위한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/ssl/cert발급된 SSL 인증서가 저장되는 디렉토리
    %NTRI_APP_HOME%/ssl/cert/backupSSL 인증서 신규/재발급 시마다 발급된 인증서가 백업되는 디렉토리
    %NTRI_APP_HOME%/curl-7.86.0_2-win64-mingwcurl 커맨드를 사용하기 위한 실행프로그램
    +

    파일 설명

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    File NameDescription
    setenv.bat + 환경변수 설정
    service-regist.bat서비스 등록
    service-edit.bat등록한 서비스정보 수정
    service-delete.bat등록한 서비스 삭제
    service-start.bat등록한 서비스 실행
    service-stop.bat등록한 서비스 중지
    service-status.bat등록한 서비스 실행 상태 확인
    service-logprint.bat등록한 서비스 실시간 로그 출력
    startup.bat서버 기동
    shutdown.bat서버 종료
    logprint.bat + 실시간 로그 출력
    +

    실행 환경

    +
      +
    • Java 버전: JDK11 이상
    • +
    • Tomcat 버전: Tomcat9 이상
    • +
    • JDBC: ojdbc8.jar
    • +
    + + diff --git a/REF/deploy/ntri/README.v0.3.1.html b/REF/deploy/ntri/README.v0.3.1.html new file mode 100644 index 0000000..4d4d65f --- /dev/null +++ b/REF/deploy/ntri/README.v0.3.1.html @@ -0,0 +1,243 @@ + + + + + + README.md + + + +

    시작하기

    +
    +

    세외수입개별시스템(Non-Tax Revenue Individual System) 은
    +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며,
    +API 4종의 데이터는 세외수입시스템측에서 제공 한다.

    +
      +
    • 출발지: 세외수입시스템
    • +
    • 목적지: 개별시스템(ntri)
    • +
    +

    버전관리

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    버전작성일작성자내용
    v0.12022.12.20박민규최초작성
    v0.22022.12.21박민규"2. SSL 인증서 발급" 내용 수정( 발급방식 변경: 스크립트 -> 실행파일(.bat) )
    v0.22022.12.21박민규%NTRI_APP_HOME%/bin/setenv.bat 파일의 "DB/SSL설정" 수정VM옵션" 환경변수 추가
    v0.32022.12.22박민규연계표준지침(v1.2.1) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json)
    v0.3.12022.12.23박민규"1. 배포하기"에 NTRI_JAVA_HOME 설정에 대한 내용 추가 및 실행 환경 JDBC 내용추가
    +

    1. 배포하기

    +
      +
    1. +

      + 원하는 경로에 ntri.zip 압축파일을 unzip 한다.

      +
        +
      • [원하는 경로]/ntri -> %NTRI_APP_HOME%
      • +
      +
    2. +
    3. +

      + %NTRI_APP_HOME%/bin/setenv.bat 파일을 열어 배포환경에 맞게 환경변수를 수정 한다.

      + +

      + ※JDK 설치 확인 방법: cmd 창에서 java -version 입력
      ※JAVA_HOME 설정 확인 방법: 시스템 -> 정보 -> 고급 시스템 설정 -> 환경 변수(N)... -> 시스템 변수(S)

      +
    4. +
    5. +

      + %NTRI_APP_HOME%/bin/service-regist.bat 파일을 "관리자권한" 으로 실행

      +
    6. +
    7. +

      + %NTRI_APP_HOME%/webapp 디렉토리에 "ntri-0.0.1-SNAPSHOT.jar" 파일 복사

      +
    8. +
    9. +

      + %NTRI_APP_HOME%/bin/service-start.bat 파일을 실행하여 "서비스 시작"

      +
        +
      • 서비스 실행 오류가 발생할 경우 %NTRI_APP_HOME%/logs/stderr.log 내용 확인
      • +
      +
    10. +
    11. +

      + %NTRI_APP_HOME%/bin/service-logprint.bat 파일을 실행하여 "서비스 실시간 로그" 확인

      +
    12. +
    +

    2. SSL 인증서 발급

    +
      +
    1. + OpenSSL 다운로드 +
        +
      • openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip
      • +
      +
    2. +
    3. 다운로드한 압축파일을 unzip 후 OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 복사
    4. +
    5. + %NTRI_APP_HOME%/ssl/bin 디렉토리의 "generate-ssl-cert-new.bat" 파일 실행
      [ 파일 설명 ]
      • 신규 발급: generate-ssl-cert-new.bat
        • 인증서파일 모두 발급(key, csr, crt)
      • 재발급: generate-ssl-cert-refresh.bat
        • 인증서파일 일부만 발급(csr, crt)
    6. +
    7. + %NTRI_APP_HOME%/ssl/cert 디렉토리에 인증서파일(key,csr,crt) 이 생성되었는지 확인
    8. +
    +

    3. API 테스트

    +
      +
    1. + "~/bin/test" 디렉토리로 이동
    2. +
    3. 테스트 배치파일(.bat) 실행하여 API 호출 +
      • 일괄: curl-all.bat
      • 부과취소: curl-LevyCancel.bat
      • 부과결과: curl-LevyResult.bat
      • 수납정보: curl-RcivInfo.bat
      • 감액정보: curl-RdcamtInfo.bat
    4. +
    +

    부록

    +
    +

    디렉토리 구성

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectoryDescription
    %NTRI_APP_HOME%/webapp어플리케이션 jar 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/testAPI 테스트 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)
    %NTRI_APP_HOME%/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)
    %NTRI_APP_HOME%/ssl/binSSL 인증서 신규/재발급을 위한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/ssl/cert발급된 SSL 인증서가 저장되는 디렉토리
    %NTRI_APP_HOME%/ssl/cert/backupSSL 인증서 신규/재발급 시마다 발급된 인증서가 백업되는 디렉토리
    %NTRI_APP_HOME%/curl-7.86.0_2-win64-mingwcurl 커맨드를 사용하기 위한 실행프로그램
    +

    파일 설명

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    File NameDescription
    setenv.bat + 환경변수 설정
    service-regist.bat서비스 등록
    service-edit.bat등록한 서비스정보 수정
    service-delete.bat등록한 서비스 삭제
    service-start.bat등록한 서비스 실행
    service-stop.bat등록한 서비스 중지
    service-status.bat등록한 서비스 실행 상태 확인
    service-logprint.bat등록한 서비스 실시간 로그 출력
    startup.bat서버 기동
    shutdown.bat서버 종료
    logprint.bat + 실시간 로그 출력
    +

    실행 환경

    +
      +
    • Java 버전: JDK11 이상
    • +
    • Tomcat 버전: Tomcat9 이상
    • +
    • JDBC: ojdbc8.jar, mariadb-java-client-2.7.5.jar, mysql-connector-java-8.0.30.jar
    • +
    + + diff --git a/REF/deploy/ntri/README.v0.3.2.html b/REF/deploy/ntri/README.v0.3.2.html new file mode 100644 index 0000000..0a25b5c --- /dev/null +++ b/REF/deploy/ntri/README.v0.3.2.html @@ -0,0 +1,249 @@ + + + + + + README.md + + + +

    시작하기

    +
    +

    세외수입개별시스템(Non-Tax Revenue Individual System) 은
    +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며,
    +API 4종의 데이터는 세외수입시스템측에서 제공 한다.

    +
      +
    • 출발지: 세외수입시스템
    • +
    • 목적지: 개별시스템(ntri)
    • +
    +

    버전관리

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    버전작성일작성자내용
    v0.12022.12.20박민규최초작성
    v0.22022.12.21박민규"2. SSL 인증서 발급" 내용 수정( 발급방식 변경: 스크립트 -> 실행파일(.bat) )
    v0.22022.12.21박민규%NTRI_APP_HOME%/bin/setenv.bat 파일의 "DB/SSL설정" 수정VM옵션" 환경변수 추가
    v0.32022.12.22박민규연계표준지침(v1.2.1) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json)
    v0.3.12022.12.23박민규"1. 배포하기"에 NTRI_JAVA_HOME 설정에 대한 내용 추가 및 실행 환경 JDBC 내용추가
    v0.3.22022.12.27박민규"부록-실행 환경"의 JDBC 수정(ojdbc8.jar -> ojdbc6.jar). 사유: 일부 서버에서 Java.sql.SQLRecoverableException 발생
    +

    1. 배포하기

    +
      +
    1. +

      + 원하는 경로에 ntri.zip 압축파일을 unzip 한다.

      +
        +
      • [원하는 경로]/ntri -> %NTRI_APP_HOME%
      • +
      +
    2. +
    3. +

      + %NTRI_APP_HOME%/bin/setenv.bat 파일을 열어 배포환경에 맞게 환경변수를 수정 한다.

      + +

      + ※JDK 설치 확인 방법: cmd 창에서 java -version 입력
      ※JAVA_HOME 설정 확인 방법: 시스템 -> 정보 -> 고급 시스템 설정 -> 환경 변수(N)... -> 시스템 변수(S)

      +
    4. +
    5. +

      + %NTRI_APP_HOME%/bin/service-regist.bat 파일을 "관리자권한" 으로 실행

      +
    6. +
    7. +

      + %NTRI_APP_HOME%/webapp 디렉토리에 "ntri-0.0.1-SNAPSHOT.jar" 파일 복사

      +
    8. +
    9. +

      + %NTRI_APP_HOME%/bin/service-start.bat 파일을 실행하여 "서비스 시작"

      +
        +
      • 서비스 실행 오류가 발생할 경우 %NTRI_APP_HOME%/logs/stderr.log 내용 확인
      • +
      +
    10. +
    11. +

      + %NTRI_APP_HOME%/bin/service-logprint.bat 파일을 실행하여 "서비스 실시간 로그" 확인

      +
    12. +
    +

    2. SSL 인증서 발급

    +
      +
    1. + OpenSSL 다운로드 +
        +
      • openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip
      • +
      +
    2. +
    3. 다운로드한 압축파일을 unzip 후 OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 복사
    4. +
    5. + %NTRI_APP_HOME%/ssl/bin 디렉토리의 "generate-ssl-cert-new.bat" 파일 실행
      [ 파일 설명 ]
      • 신규 발급: generate-ssl-cert-new.bat
        • 인증서파일 모두 발급(key, csr, crt)
      • 재발급: generate-ssl-cert-refresh.bat
        • 인증서파일 일부만 발급(csr, crt)
    6. +
    7. + %NTRI_APP_HOME%/ssl/cert 디렉토리에 인증서파일(key,csr,crt) 이 생성되었는지 확인
    8. +
    +

    3. API 테스트

    +
      +
    1. + "~/bin/test" 디렉토리로 이동
    2. +
    3. 테스트 배치파일(.bat) 실행하여 API 호출 +
      • 일괄: curl-all.bat
      • 부과취소: curl-LevyCancel.bat
      • 부과결과: curl-LevyResult.bat
      • 수납정보: curl-RcivInfo.bat
      • 감액정보: curl-RdcamtInfo.bat
    4. +
    +

    부록

    +
    +

    디렉토리 구성

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectoryDescription
    %NTRI_APP_HOME%/webapp어플리케이션 jar 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/testAPI 테스트 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)
    %NTRI_APP_HOME%/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)
    %NTRI_APP_HOME%/ssl/binSSL 인증서 신규/재발급을 위한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/ssl/cert발급된 SSL 인증서가 저장되는 디렉토리
    %NTRI_APP_HOME%/ssl/cert/backupSSL 인증서 신규/재발급 시마다 발급된 인증서가 백업되는 디렉토리
    %NTRI_APP_HOME%/curl-7.86.0_2-win64-mingwcurl 커맨드를 사용하기 위한 실행프로그램
    +

    파일 설명

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    File NameDescription
    setenv.bat + 환경변수 설정
    service-regist.bat서비스 등록
    service-edit.bat등록한 서비스정보 수정
    service-delete.bat등록한 서비스 삭제
    service-start.bat등록한 서비스 실행
    service-stop.bat등록한 서비스 중지
    service-status.bat등록한 서비스 실행 상태 확인
    service-logprint.bat등록한 서비스 실시간 로그 출력
    startup.bat서버 기동
    shutdown.bat서버 종료
    logprint.bat + 실시간 로그 출력
    +

    실행 환경

    +
      +
    • Java 버전: JDK11 이상
    • +
    • Tomcat 버전: Tomcat9 이상
    • +
    • JDBC: ojdbc6.jar, mariadb-java-client-2.7.5.jar, mysql-connector-java-8.0.30.jar
    • +
    + + diff --git a/REF/deploy/ntri/README.v0.3.3.html b/REF/deploy/ntri/README.v0.3.3.html new file mode 100644 index 0000000..f089312 --- /dev/null +++ b/REF/deploy/ntri/README.v0.3.3.html @@ -0,0 +1,258 @@ + + + + + + README.md + + + +

    시작하기

    +
    +

    세외수입개별시스템(Non-Tax Revenue Individual System) 은
    +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며,
    +API 4종의 데이터는 세외수입시스템측에서 제공 한다.

    +
      +
    • 출발지: 세외수입시스템
    • +
    • 목적지: 개별시스템(ntri)
    • +
    +

    버전관리

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    버전작성일작성자내용
    v0.12022.12.20박민규최초작성
    v0.22022.12.21박민규"2. SSL 인증서 발급" 내용 수정( 발급방식 변경: 스크립트 -> 실행파일(.bat) )
    v0.22022.12.21박민규%NTRI_APP_HOME%/bin/setenv.bat 파일의 "DB/SSL설정" 수정VM옵션" 환경변수 추가
    v0.32022.12.22박민규연계표준지침(v1.2.1) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json)
    v0.3.12022.12.23박민규"1. 배포하기"에 NTRI_JAVA_HOME 설정에 대한 내용 추가 및 실행 환경 JDBC 내용추가
    v0.3.22022.12.27박민규"부록-실행 환경"의 JDBC 수정(ojdbc8.jar -> ojdbc6.jar). 사유: 일부 서버에서 Java.sql.SQLRecoverableException 발생
    v0.3.32022.12.27박민규문서내용 수정. "부록-실행 환경" 삭제. "부록-구현 스펙" 추가
    +

    1. 배포하기

    +
      +
    1. +

      + 원하는 경로에 ntri.zip 압축파일을 unzip 한다.

      +
        +
      • [원하는 경로]/ntri -> %NTRI_APP_HOME%
      • +
      +
    2. +
    3. +

      + %NTRI_APP_HOME%/bin/setenv.bat 파일을 열어 배포환경에 맞게 환경변수를 수정 한다.

      + +

      + ※JDK 설치 확인 방법: cmd 창에서 java -version 입력
      ※JAVA_HOME 설정 확인 방법: 시스템 -> 정보 -> 고급 시스템 설정 -> 환경 변수(N)... -> 시스템 변수(S)

      +
    4. +
    5. +

      + %NTRI_APP_HOME%/bin/service-regist.bat 파일을 "관리자권한" 으로 실행

      +
    6. +
    7. +

      + %NTRI_APP_HOME%/webapp 디렉토리에 "ntri-0.0.1-SNAPSHOT.jar" 파일 복사

      +
    8. +
    9. +

      + %NTRI_APP_HOME%/bin/service-start.bat 파일을 실행하여 "서비스 시작"

      +
        +
      • 서비스 실행 오류가 발생할 경우 %NTRI_APP_HOME%/logs/stderr.log 내용 확인
      • +
      +
    10. +
    11. +

      + %NTRI_APP_HOME%/bin/service-logprint.bat 파일을 실행하여 "서비스 실시간 로그" 확인

      +
    12. +
    +

    2. SSL 인증서 발급

    +
      +
    1. + OpenSSL 다운로드 +
        +
      • openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip
      • +
      +
    2. +
    3. 다운로드한 압축파일을 unzip 후 OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 복사
    4. +
    5. + %NTRI_APP_HOME%/ssl/bin 디렉토리의 "generate-ssl-cert-new.bat" 파일 실행
      [ 파일 설명 ]
      • 신규 발급: generate-ssl-cert-new.bat
        • 인증서파일 모두 발급(key, csr, crt)
      • 재발급: generate-ssl-cert-refresh.bat
        • 인증서파일 일부만 발급(csr, crt)
    6. +
    7. + %NTRI_APP_HOME%/ssl/cert 디렉토리에 인증서파일(key,csr,crt) 이 생성되었는지 확인
    8. +
    +

    3. API 테스트

    +
      +
    1. + "~/bin/test" 디렉토리로 이동
    2. +
    3. 테스트 배치파일(.bat) 실행하여 API 호출 +
      • 일괄: curl-all.bat
      • 부과취소: curl-LevyCancel.bat
      • 부과결과: curl-LevyResult.bat
      • 수납정보: curl-RcivInfo.bat
      • 감액정보: curl-RdcamtInfo.bat
    4. +
    +

    부록

    +
    +

    디렉토리 구성

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectoryDescription
    %NTRI_APP_HOME%/webapp어플리케이션 jar 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/testAPI 테스트 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)
    %NTRI_APP_HOME%/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)
    %NTRI_APP_HOME%/ssl/binSSL 인증서 신규/재발급을 위한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/ssl/cert발급된 SSL 인증서가 저장되는 디렉토리
    %NTRI_APP_HOME%/ssl/cert/backupSSL 인증서 신규/재발급 시마다 발급된 인증서가 백업되는 디렉토리
    %NTRI_APP_HOME%/curl-7.86.0_2-win64-mingwcurl 커맨드를 사용하기 위한 실행프로그램
    +

    파일 설명

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    File NameDescription
    setenv.bat + 환경변수 설정
    service-regist.bat서비스 등록
    service-edit.bat등록한 서비스정보 수정
    service-delete.bat등록한 서비스 삭제
    service-start.bat등록한 서비스 실행
    service-stop.bat등록한 서비스 중지
    service-status.bat등록한 서비스 실행 상태 확인
    service-logprint.bat등록한 서비스 실시간 로그 출력
    startup.bat서버 기동
    shutdown.bat서버 종료
    logprint.bat + 실시간 로그 출력
    +

    구현 스펙

    +
      +
    • Back-End +
      • SpringBoot 2.7.5
      • Tomcat 9.0.68
      • JDK11
      • gradle
      • JPA
    • +
    • DB +
      • Oracle 11g
      • mariaDB 10.6.5
      • mysql
    • +
    • JDBC Libray +
      • ojdbc6.jar
      • mariadb-java-client-2.7.5.jar
      • mysql-connector-java-8.0.30.jar
    • +
    + + diff --git a/REF/deploy/ntri/README.v0.3.html b/REF/deploy/ntri/README.v0.3.html new file mode 100644 index 0000000..8020918 --- /dev/null +++ b/REF/deploy/ntri/README.v0.3.html @@ -0,0 +1,211 @@ + + + + + + README.md + + + +

    시작하기

    +
    +

    세외수입개별시스템(Non-Tax Revenue Individual System) 은
    +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며,
    +API 4종의 데이터는 세외수입시스템측에서 제공 한다.

    +
      +
    • 출발지: 세외수입시스템
    • +
    • 목적지: 개별시스템(ntri)
    • +
    +

    버전관리

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    버전작성일작성자내용
    v0.12022.12.20박민규최초작성
    v0.22022.12.21박민규"2. SSL 인증서 발급" 내용 수정( 발급방식 변경: 스크립트 -> 실행파일(.bat) )
    v0.22022.12.21박민규%NTRI_APP_HOME%/bin/setenv.bat 파일의 "DB/SSL설정" 수정VM옵션" 환경변수 추가
    v0.32022.12.22박민규연계표준지침(v1.2.1) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json)
    +

    1. 배포하기

    +
      +
    1. + 원하는 경로에 ntri.zip 압축파일을 unzip 한다. +
      • [원하는 경로]/ntri -> %NTRI_APP_HOME%
    2. +
    3. + %NTRI_APP_HOME%/bin/setenv.bat 파일을 열어 배포환경에 맞게 환경변수를 수정 한다. +
      • NTRI_JAVA_HOME 및 SSL/DB 설정 등..
    4. +
    5. + %NTRI_APP_HOME%/bin/service-regist.bat 파일을 "관리자권한" 으로 실행
    6. +
    7. + %NTRI_APP_HOME%/webapp 디렉토리에 "ntri-0.0.1-SNAPSHOT.jar" 파일 복사
    8. +
    9. + %NTRI_APP_HOME%/bin/service-start.bat 파일을 실행하여 "서비스 시작" +
      • 서비스 실행 오류가 발생할 경우 %NTRI_APP_HOME%/logs/stderr.log 내용 확인
    10. +
    11. + %NTRI_APP_HOME%/bin/service-logprint.bat 파일을 실행하여 "서비스 실시간 로그" 확인
    12. +
    +

    2. SSL 인증서 발급

    +
      +
    1. OpenSSL 다운로드(https://sourceforge.net/projects/openssl) +
      • openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip
    2. +
    3. 다운로드한 압축파일을 unzip 후 OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 복사
    4. +
    5. + %NTRI_APP_HOME%/ssl/bin 디렉토리의 "generate-ssl-cert-new.bat" 파일 실행
      [ 파일 설명 ]
      • 신규 발급: generate-ssl-cert-new.bat
        • 인증서파일 모두 발급(key, csr, crt)
      • 재발급: generate-ssl-cert-refresh.bat
        • 인증서파일 일부만 발급(csr, crt)
    6. +
    7. + %NTRI_APP_HOME%/ssl/cert 디렉토리에 인증서파일(key,csr,crt) 이 생성되었는지 확인
    8. +
    +

    3. API 테스트

    +
      +
    1. + "~/bin/test" 디렉토리로 이동
    2. +
    3. 테스트 배치파일(.bat) 실행하여 API 호출 +
      • 일괄: curl-all.bat
      • 부과취소: curl-LevyCancel.bat
      • 부과결과: curl-LevyResult.bat
      • 수납정보: curl-RcivInfo.bat
      • 감액정보: curl-RdcamtInfo.bat
    4. +
    +

    부록

    +
    +

    디렉토리 구성

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectoryDescription
    %NTRI_APP_HOME%/webapp어플리케이션 jar 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/testAPI 테스트 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)
    %NTRI_APP_HOME%/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)
    %NTRI_APP_HOME%/ssl/binSSL 인증서 신규/재발급을 위한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/ssl/cert발급된 SSL 인증서가 저장되는 디렉토리
    %NTRI_APP_HOME%/ssl/cert/backupSSL 인증서 신규/재발급 시마다 발급된 인증서가 백업되는 디렉토리
    %NTRI_APP_HOME%/curl-7.86.0_2-win64-mingwcurl 커맨드를 사용하기 위한 실행프로그램
    +

    파일 설명

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    File NameDescription
    setenv.bat + 환경변수 설정
    service-regist.bat서비스 등록
    service-edit.bat등록한 서비스정보 수정
    service-delete.bat등록한 서비스 삭제
    service-start.bat등록한 서비스 실행
    service-stop.bat등록한 서비스 중지
    service-status.bat등록한 서비스 실행 상태 확인
    service-logprint.bat등록한 서비스 실시간 로그 출력
    startup.bat서버 기동
    shutdown.bat서버 종료
    logprint.bat + 실시간 로그 출력
    +

    실행 환경

    +
      +
    • Java 버전: JDK11 이상
    • +
    • Tomcat 버전: Tomcat9 이상
    • +
    • JDBC: ojdbc8.jar
    • +
    + + diff --git a/REF/deploy/ntri/README.v0.4.1.html b/REF/deploy/ntri/README.v0.4.1.html new file mode 100644 index 0000000..bf05853 --- /dev/null +++ b/REF/deploy/ntri/README.v0.4.1.html @@ -0,0 +1,266 @@ + + + + + + README.md + + + +

    시작하기

    +
    +

    세외수입개별시스템(Non-Tax Revenue Individual System) 은
    +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며,
    +API 4종의 데이터는 세외수입시스템측에서 제공 한다.

    +
      +
    • 출발지: 세외수입시스템
    • +
    • 목적지: 개별시스템(ntri)
    • +
    +

    버전관리

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    버전작성일작성자내용
    v0.12022.12.20박민규최초작성
    v0.22022.12.21박민규"2. SSL 인증서 발급" 내용 수정( 발급방식 변경: 스크립트 -> 실행파일(.bat) )
    v0.22022.12.21박민규%NTRI_APP_HOME%/bin/setenv.bat 파일의 "DB/SSL설정" 수정VM옵션" 환경변수 추가
    v0.32022.12.22박민규연계표준지침(v1.2.1) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json)
    v0.3.12022.12.23박민규"1. 배포하기"에 NTRI_JAVA_HOME 설정에 대한 내용 추가 및 실행 환경 JDBC 내용추가
    v0.3.22022.12.27박민규"부록-실행 환경"의 JDBC 수정(ojdbc8.jar -> ojdbc6.jar). 사유: 일부 서버에서 Java.sql.SQLRecoverableException 발생
    v0.3.32022.12.27박민규문서내용 수정. "부록-실행 환경" 삭제. "부록-구현 스펙" 추가
    v0.42022.12.27박민규연계표준지침(v1.2.1 -> v1.?.?) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json). reqVo 필드타입 수정(단건 -> 다건)
    v0.4.12022.12.29박민규curl프로그램 변경 및 프로그램 위치 변경(%NTRI_APP_HOME% -> %NTRI_APP_HOME%/bin/test). "부록-디렉토리 구성"에서 내용 삭제
    +

    1. 배포하기

    +
      +
    1. +

      + 원하는 경로에 ntri.zip 압축파일을 unzip 한다.

      +
        +
      • [원하는 경로]/ntri -> %NTRI_APP_HOME%
      • +
      +
    2. +
    3. +

      + %NTRI_APP_HOME%/bin/setenv.bat 파일을 열어 배포환경에 맞게 환경변수를 수정 한다.

      + +

      + ※JDK 설치 확인 방법: cmd 창에서 java -version 입력
      ※JAVA_HOME 설정 확인 방법: 시스템 -> 정보 -> 고급 시스템 설정 -> 환경 변수(N)... -> 시스템 변수(S)

      +
    4. +
    5. +

      + %NTRI_APP_HOME%/bin/service-regist.bat 파일을 "관리자권한" 으로 실행

      +
    6. +
    7. +

      + %NTRI_APP_HOME%/webapp 디렉토리에 "ntri-0.0.1-SNAPSHOT.jar" 파일 복사

      +
    8. +
    9. +

      + %NTRI_APP_HOME%/bin/service-start.bat 파일을 실행하여 "서비스 시작"

      +
        +
      • 서비스 실행 오류가 발생할 경우 %NTRI_APP_HOME%/logs/stderr.log 내용 확인
      • +
      +
    10. +
    11. +

      + %NTRI_APP_HOME%/bin/service-logprint.bat 파일을 실행하여 "서비스 실시간 로그" 확인

      +
    12. +
    +

    2. SSL 인증서 발급

    +
      +
    1. + OpenSSL 다운로드 +
        +
      • openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip
      • +
      +
    2. +
    3. 다운로드한 압축파일을 unzip 후 OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 복사
    4. +
    5. + %NTRI_APP_HOME%/ssl/bin 디렉토리의 "generate-ssl-cert-new.bat" 파일 실행
      [ 파일 설명 ]
      • 신규 발급: generate-ssl-cert-new.bat
        • 인증서파일 모두 발급(key, csr, crt)
      • 재발급: generate-ssl-cert-refresh.bat
        • 인증서파일 일부만 발급(csr, crt)
    6. +
    7. + %NTRI_APP_HOME%/ssl/cert 디렉토리에 인증서파일(key,csr,crt) 이 생성되었는지 확인
    8. +
    +

    3. API 테스트

    +
      +
    1. + "~/bin/test" 디렉토리로 이동
    2. +
    3. 테스트 배치파일(.bat) 실행하여 API 호출 +
      • 일괄: curl-all.bat
      • 부과취소: curl-LevyCancel.bat
      • 부과결과: curl-LevyResult.bat
      • 수납정보: curl-RcivInfo.bat
      • 감액정보: curl-RdcamtInfo.bat
    4. +
    +

    부록

    +
    +

    디렉토리 구성

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectoryDescription
    %NTRI_APP_HOME%/webapp어플리케이션 jar 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/testAPI 테스트 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)
    %NTRI_APP_HOME%/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)
    %NTRI_APP_HOME%/ssl/binSSL 인증서 신규/재발급을 위한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/ssl/cert발급된 SSL 인증서가 저장되는 디렉토리
    %NTRI_APP_HOME%/ssl/cert/backupSSL 인증서 신규/재발급 시마다 발급된 인증서가 백업되는 디렉토리
    +

    파일 설명

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    File NameDescription
    setenv.bat + 환경변수 설정
    service-regist.bat서비스 등록
    service-edit.bat등록한 서비스정보 수정
    service-delete.bat등록한 서비스 삭제
    service-start.bat등록한 서비스 실행
    service-stop.bat등록한 서비스 중지
    service-status.bat등록한 서비스 실행 상태 확인
    service-logprint.bat등록한 서비스 실시간 로그 출력
    startup.bat서버 기동
    shutdown.bat서버 종료
    logprint.bat + 실시간 로그 출력
    +

    구현 스펙

    +
      +
    • Back-End +
      • SpringBoot 2.7.5
      • Tomcat 9.0.68
      • JDK11
      • gradle
      • JPA
    • +
    • DB +
      • Oracle 11g
      • mariaDB 10.6.5
      • mysql
    • +
    • JDBC Libray +
      • ojdbc6.jar
      • mariadb-java-client-2.7.5.jar
      • mysql-connector-java-8.0.30.jar
    • +
    + + diff --git a/REF/deploy/ntri/README.v0.4.html b/REF/deploy/ntri/README.v0.4.html new file mode 100644 index 0000000..d1e3371 --- /dev/null +++ b/REF/deploy/ntri/README.v0.4.html @@ -0,0 +1,264 @@ + + + + + + README.md + + + +

    시작하기

    +
    +

    세외수입개별시스템(Non-Tax Revenue Individual System) 은
    +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며,
    +API 4종의 데이터는 세외수입시스템측에서 제공 한다.

    +
      +
    • 출발지: 세외수입시스템
    • +
    • 목적지: 개별시스템(ntri)
    • +
    +

    버전관리

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    버전작성일작성자내용
    v0.12022.12.20박민규최초작성
    v0.22022.12.21박민규"2. SSL 인증서 발급" 내용 수정( 발급방식 변경: 스크립트 -> 실행파일(.bat) )
    v0.22022.12.21박민규%NTRI_APP_HOME%/bin/setenv.bat 파일의 "DB/SSL설정" 수정VM옵션" 환경변수 추가
    v0.32022.12.22박민규연계표준지침(v1.2.1) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json)
    v0.3.12022.12.23박민규"1. 배포하기"에 NTRI_JAVA_HOME 설정에 대한 내용 추가 및 실행 환경 JDBC 내용추가
    v0.3.22022.12.27박민규"부록-실행 환경"의 JDBC 수정(ojdbc8.jar -> ojdbc6.jar). 사유: 일부 서버에서 Java.sql.SQLRecoverableException 발생
    v0.3.32022.12.27박민규문서내용 수정. "부록-실행 환경" 삭제. "부록-구현 스펙" 추가
    v0.42022.12.27박민규연계표준지침(v1.2.1 -> v1.?.?) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json). reqVo 필드타입 수정(단건 -> 다건)
    +

    1. 배포하기

    +
      +
    1. +

      + 원하는 경로에 ntri.zip 압축파일을 unzip 한다.

      +
        +
      • [원하는 경로]/ntri -> %NTRI_APP_HOME%
      • +
      +
    2. +
    3. +

      + %NTRI_APP_HOME%/bin/setenv.bat 파일을 열어 배포환경에 맞게 환경변수를 수정 한다.

      + +

      + ※JDK 설치 확인 방법: cmd 창에서 java -version 입력
      ※JAVA_HOME 설정 확인 방법: 시스템 -> 정보 -> 고급 시스템 설정 -> 환경 변수(N)... -> 시스템 변수(S)

      +
    4. +
    5. +

      + %NTRI_APP_HOME%/bin/service-regist.bat 파일을 "관리자권한" 으로 실행

      +
    6. +
    7. +

      + %NTRI_APP_HOME%/webapp 디렉토리에 "ntri-0.0.1-SNAPSHOT.jar" 파일 복사

      +
    8. +
    9. +

      + %NTRI_APP_HOME%/bin/service-start.bat 파일을 실행하여 "서비스 시작"

      +
        +
      • 서비스 실행 오류가 발생할 경우 %NTRI_APP_HOME%/logs/stderr.log 내용 확인
      • +
      +
    10. +
    11. +

      + %NTRI_APP_HOME%/bin/service-logprint.bat 파일을 실행하여 "서비스 실시간 로그" 확인

      +
    12. +
    +

    2. SSL 인증서 발급

    +
      +
    1. + OpenSSL 다운로드 +
        +
      • openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip
      • +
      +
    2. +
    3. 다운로드한 압축파일을 unzip 후 OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 복사
    4. +
    5. + %NTRI_APP_HOME%/ssl/bin 디렉토리의 "generate-ssl-cert-new.bat" 파일 실행
      [ 파일 설명 ]
      • 신규 발급: generate-ssl-cert-new.bat
        • 인증서파일 모두 발급(key, csr, crt)
      • 재발급: generate-ssl-cert-refresh.bat
        • 인증서파일 일부만 발급(csr, crt)
    6. +
    7. + %NTRI_APP_HOME%/ssl/cert 디렉토리에 인증서파일(key,csr,crt) 이 생성되었는지 확인
    8. +
    +

    3. API 테스트

    +
      +
    1. + "~/bin/test" 디렉토리로 이동
    2. +
    3. 테스트 배치파일(.bat) 실행하여 API 호출 +
      • 일괄: curl-all.bat
      • 부과취소: curl-LevyCancel.bat
      • 부과결과: curl-LevyResult.bat
      • 수납정보: curl-RcivInfo.bat
      • 감액정보: curl-RdcamtInfo.bat
    4. +
    +

    부록

    +
    +

    디렉토리 구성

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectoryDescription
    %NTRI_APP_HOME%/webapp어플리케이션 jar 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/testAPI 테스트 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)
    %NTRI_APP_HOME%/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)
    %NTRI_APP_HOME%/ssl/binSSL 인증서 신규/재발급을 위한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/ssl/cert발급된 SSL 인증서가 저장되는 디렉토리
    %NTRI_APP_HOME%/ssl/cert/backupSSL 인증서 신규/재발급 시마다 발급된 인증서가 백업되는 디렉토리
    %NTRI_APP_HOME%/curl-7.86.0_2-win64-mingwcurl 커맨드를 사용하기 위한 실행프로그램
    +

    파일 설명

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    File NameDescription
    setenv.bat + 환경변수 설정
    service-regist.bat서비스 등록
    service-edit.bat등록한 서비스정보 수정
    service-delete.bat등록한 서비스 삭제
    service-start.bat등록한 서비스 실행
    service-stop.bat등록한 서비스 중지
    service-status.bat등록한 서비스 실행 상태 확인
    service-logprint.bat등록한 서비스 실시간 로그 출력
    startup.bat서버 기동
    shutdown.bat서버 종료
    logprint.bat + 실시간 로그 출력
    +

    구현 스펙

    +
      +
    • Back-End +
      • SpringBoot 2.7.5
      • Tomcat 9.0.68
      • JDK11
      • gradle
      • JPA
    • +
    • DB +
      • Oracle 11g
      • mariaDB 10.6.5
      • mysql
    • +
    • JDBC Libray +
      • ojdbc6.jar
      • mariadb-java-client-2.7.5.jar
      • mysql-connector-java-8.0.30.jar
    • +
    + + diff --git a/REF/deploy/ntri/README.v0.5.html b/REF/deploy/ntri/README.v0.5.html new file mode 100644 index 0000000..7c15a10 --- /dev/null +++ b/REF/deploy/ntri/README.v0.5.html @@ -0,0 +1,272 @@ + + + + + + README.md + + + +

    시작하기

    +
    +

    세외수입개별시스템(Non-Tax Revenue Individual System) 은
    +과태료 부과에 대한 실시간 API 4종(부과결과/부과취소/수납정보/감액정보)을 지원 하며,
    +API 4종의 데이터는 세외수입시스템측에서 제공 한다.

    +
      +
    • 출발지: 세외수입시스템
    • +
    • 목적지: 개별시스템(ntri)
    • +
    +

    버전관리

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    버전작성일작성자내용
    v0.12022.12.20박민규최초작성
    v0.22022.12.21박민규"2. SSL 인증서 발급" 내용 수정( 발급방식 변경: 스크립트 -> 실행파일(.bat) )
    v0.22022.12.21박민규%NTRI_APP_HOME%/bin/setenv.bat 파일의 "DB/SSL설정" 수정VM옵션" 환경변수 추가
    v0.32022.12.22박민규연계표준지침(v1.2.1) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json)
    v0.3.12022.12.23박민규"1. 배포하기"에 NTRI_JAVA_HOME 설정에 대한 내용 추가 및 실행 환경 JDBC 내용추가
    v0.3.22022.12.27박민규"부록-실행 환경"의 JDBC 수정(ojdbc8.jar -> ojdbc6.jar). 사유: 일부 서버에서 Java.sql.SQLRecoverableException 발생
    v0.3.32022.12.27박민규문서내용 수정. "부록-실행 환경" 삭제. "부록-구현 스펙" 추가
    v0.42022.12.27박민규연계표준지침(v1.2.1 -> v1.?.?) 전문구조 변경에 의한 "API 테스트" 데이터 수정(%NTRI_APP_HOME%/bin/test/*.json). reqVo 필드타입 수정(단건 -> 다건)
    v0.4.12022.12.29박민규curl프로그램 변경 및 프로그램 위치 변경(%NTRI_APP_HOME% -> %NTRI_APP_HOME%/bin/test). "부록-디렉토리 구성"에서 내용 삭제
    v0.52023.01.02박민규연계대상코드(linkTrgtCd) 설정 추가. (어플리케이션 수정 및 setenv.bat 환경변수 NTRI_APP_LINKTRGTCD 추가)
    +

    1. 배포하기

    +
      +
    1. +

      + 원하는 경로에 ntri.zip 압축파일을 unzip 한다.

      +
        +
      • [원하는 경로]/ntri -> %NTRI_APP_HOME%
      • +
      +
    2. +
    3. +

      + %NTRI_APP_HOME%/bin/setenv.bat 파일을 열어 배포환경에 맞게 환경변수를 수정 한다.

      + +

      + ※JDK 설치 확인 방법: cmd 창에서 java -version 입력
      ※JAVA_HOME 설정 확인 방법: 시스템 -> 정보 -> 고급 시스템 설정 -> 환경 변수(N)... -> 시스템 변수(S)

      +
    4. +
    5. +

      + %NTRI_APP_HOME%/bin/service-regist.bat 파일을 "관리자권한" 으로 실행

      +
    6. +
    7. +

      + %NTRI_APP_HOME%/webapp 디렉토리에 "ntri-0.0.1-SNAPSHOT.jar" 파일 복사

      +
    8. +
    9. +

      + %NTRI_APP_HOME%/bin/service-start.bat 파일을 실행하여 "서비스 시작"

      +
        +
      • 서비스 실행 오류가 발생할 경우 %NTRI_APP_HOME%/logs/stderr.log 내용 확인
      • +
      +
    10. +
    11. +

      + %NTRI_APP_HOME%/bin/service-logprint.bat 파일을 실행하여 "서비스 실시간 로그" 확인

      +
    12. +
    +

    2. SSL 인증서 발급

    +
      +
    1. + OpenSSL 다운로드 +
        +
      • openssl-1.0.2j-fips-x86_64/openssl-1.0.2j-fips-x86_64.zip
      • +
      +
    2. +
    3. 다운로드한 압축파일을 unzip 후 OpenSSL 디렉토리를 C드라이브(C:/) 밑으로 복사
    4. +
    5. + %NTRI_APP_HOME%/ssl/bin 디렉토리의 "generate-ssl-cert-new.bat" 파일 실행
      [ 파일 설명 ]
      • 신규 발급: generate-ssl-cert-new.bat
        • 인증서파일 모두 발급(key, csr, crt)
      • 재발급: generate-ssl-cert-refresh.bat
        • 인증서파일 일부만 발급(csr, crt)
    6. +
    7. + %NTRI_APP_HOME%/ssl/cert 디렉토리에 인증서파일(key,csr,crt) 이 생성되었는지 확인
    8. +
    +

    3. API 테스트

    +
      +
    1. + "~/bin/test" 디렉토리로 이동
    2. +
    3. 테스트 배치파일(.bat) 실행하여 API 호출 +
      • 일괄: curl-all.bat
      • 부과취소: curl-LevyCancel.bat
      • 부과결과: curl-LevyResult.bat
      • 수납정보: curl-RcivInfo.bat
      • 감액정보: curl-RdcamtInfo.bat
    4. +
    +

    부록

    +
    +

    디렉토리 구성

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectoryDescription
    %NTRI_APP_HOME%/webapp어플리케이션 jar 파일이 위치한 디렉토리
    %NTRI_APP_HOME%/bin서버기동과 관련한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/testAPI 테스트 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/bin/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(startup.bat 직접 호출 시)
    %NTRI_APP_HOME%/logs어플리케이션 로그파일(.log)이 저장되는 디렉토리(윈도우 서비스 사용 시)
    %NTRI_APP_HOME%/ssl/binSSL 인증서 신규/재발급을 위한 배치파일(.bat)이 위치한 디렉토리
    %NTRI_APP_HOME%/ssl/cert발급된 SSL 인증서가 저장되는 디렉토리
    %NTRI_APP_HOME%/ssl/cert/backupSSL 인증서 신규/재발급 시마다 발급된 인증서가 백업되는 디렉토리
    +

    파일 설명

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    File NameDescription
    setenv.bat + 환경변수 설정
    service-regist.bat서비스 등록
    service-edit.bat등록한 서비스정보 수정
    service-delete.bat등록한 서비스 삭제
    service-start.bat등록한 서비스 실행
    service-stop.bat등록한 서비스 중지
    service-status.bat등록한 서비스 실행 상태 확인
    service-logprint.bat등록한 서비스 실시간 로그 출력
    startup.bat서버 기동
    shutdown.bat서버 종료
    logprint.bat + 실시간 로그 출력
    +

    구현 스펙

    +
      +
    • Back-End +
      • SpringBoot 2.7.5
      • Tomcat 9.0.68
      • JDK11
      • gradle
      • JPA
    • +
    • DB +
      • Oracle 11g
      • mariaDB 10.6.5
      • mysql
    • +
    • JDBC Libray +
      • ojdbc6.jar
      • mariadb-java-client-2.7.5.jar
      • mysql-connector-java-8.0.30.jar
    • +
    + + diff --git a/REF/doc/v1.0/차세대 세외수입행정 개별시스템 연계 표준지침_v1.0.hwp b/REF/doc/v1.0/차세대 세외수입행정 개별시스템 연계 표준지침_v1.0.hwp new file mode 100644 index 0000000..c6cc495 Binary files /dev/null and b/REF/doc/v1.0/차세대 세외수입행정 개별시스템 연계 표준지침_v1.0.hwp differ diff --git a/REF/doc/v1.2.1/차세대 세외수입행정 개별시스템 연계 표준지침_v1.21.pdf b/REF/doc/v1.2.1/차세대 세외수입행정 개별시스템 연계 표준지침_v1.21.pdf new file mode 100644 index 0000000..1f9a799 Binary files /dev/null and b/REF/doc/v1.2.1/차세대 세외수입행정 개별시스템 연계 표준지침_v1.21.pdf differ diff --git a/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내.pdf b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내.pdf new file mode 100644 index 0000000..7ea6bde Binary files /dev/null and b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내.pdf differ diff --git a/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임1] 차세대 세외수입 개별·특화시스템 연계 테스트 안내 사항.pdf b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임1] 차세대 세외수입 개별·특화시스템 연계 테스트 안내 사항.pdf new file mode 100644 index 0000000..3e57e29 Binary files /dev/null and b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임1] 차세대 세외수입 개별·특화시스템 연계 테스트 안내 사항.pdf differ diff --git a/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨1] 차세대 세외수입행정 개별·특화시스템 연계목록 인터페이스ID정보.xlsx b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨1] 차세대 세외수입행정 개별·특화시스템 연계목록 인터페이스ID정보.xlsx new file mode 100644 index 0000000..9c34693 Binary files /dev/null and b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨1] 차세대 세외수입행정 개별·특화시스템 연계목록 인터페이스ID정보.xlsx differ diff --git a/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨2] 차세대 세외수입행정 지방자치단체_시스템_시스템코드정보.xlsx b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨2] 차세대 세외수입행정 지방자치단체_시스템_시스템코드정보.xlsx new file mode 100644 index 0000000..2f75e83 Binary files /dev/null and b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨2] 차세대 세외수입행정 지방자치단체_시스템_시스템코드정보.xlsx differ diff --git a/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨3] 차세대 세외수입행정 대표세입과목+운영항목.xlsx b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨3] 차세대 세외수입행정 대표세입과목+운영항목.xlsx new file mode 100644 index 0000000..2d89037 Binary files /dev/null and b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨3] 차세대 세외수입행정 대표세입과목+운영항목.xlsx differ diff --git a/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨4] 차세대 세외수입행정 특별회계사업코드_전국공통_개별_특화시스템_안내용.xlsx b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨4] 차세대 세외수입행정 특별회계사업코드_전국공통_개별_특화시스템_안내용.xlsx new file mode 100644 index 0000000..9bb4ef4 Binary files /dev/null and b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨4] 차세대 세외수입행정 특별회계사업코드_전국공통_개별_특화시스템_안내용.xlsx differ diff --git a/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨5] 연계테스트 확인서(양식).hwp b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨5] 연계테스트 확인서(양식).hwp new file mode 100644 index 0000000..c54e086 Binary files /dev/null and b/REF/doc/v1.2/[본문] 차세대 세외수입시스템과 자치단체 개별 및 특화시스템간 연계 테스트 안내외2 (1)/[붙임] [붙임2] 차세대 세외수입 개별·특화시스템 관련 별첨 자료 일체/[별첨5] 연계테스트 확인서(양식).hwp differ diff --git a/REF/doc/v1.2/차세대 세외수입행정 개별시스템 연계 표준지침_v1.2.pdf b/REF/doc/v1.2/차세대 세외수입행정 개별시스템 연계 표준지침_v1.2.pdf new file mode 100644 index 0000000..9694b69 Binary files /dev/null and b/REF/doc/v1.2/차세대 세외수입행정 개별시스템 연계 표준지침_v1.2.pdf differ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..ba3ebd3 --- /dev/null +++ b/build.gradle @@ -0,0 +1,125 @@ +plugins { + id 'org.springframework.boot' version '2.7.5' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id 'org.asciidoctor.convert' version '1.5.8' + id 'java' +} + +group = 'cokr.xit.ntri' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '11' + +repositories { + mavenCentral() +} + +ext { + set('snippetsDir', file("build/generated-snippets")) +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-configuration-processor' + runtimeOnly 'com.oracle.database.jdbc:ojdbc8' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + + /*==================================================================================== + * Springdoc - swagger + ====================================================================================*/ + implementation 'org.springdoc:springdoc-openapi-ui:1.6.3' + + /*==================================================================================== + * lombok + ====================================================================================*/ + implementation 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + /*==================================================================================== + * commons-io + ====================================================================================*/ + implementation 'org.apache.commons:commons-io:1.3.2' + + /*==================================================================================== + * jdbc library + ====================================================================================*/ + implementation 'org.mariadb.jdbc:mariadb-java-client:2.7.5' + implementation 'mysql:mysql-connector-java:8.0.30' + //TODO: "java.sql.SQLException: 지원되지 않는 문자 집합(클래스 경로에 orai18n.jar 추가): KO16MSWIN949" 에러 발생 시 추가 + implementation 'com.oracle.ojdbc:orai18n:19.3.0.0' + + + /*==================================================================================== + * external library + ====================================================================================*/ + implementation fileTree(dir: 'libs', includes: ['*.jar']) +// implementation files("libs/ojdbc8.jar") +} + +//processResources { +// filesMatching('**/application.yml') { +// expand(project.properties) +// } +//} +//import org.apache.tools.ant.filters.ReplaceTokens +//processResources { +// with copySpec { +// from 'src/main/resources' +// include '**/application.yml' +//// include '**/application*.yaml' +//// include '**/application*.properties' +// project.properties.findAll().each { +// prop -> +// if (prop.value != null) { +// filter(ReplaceTokens, tokens: [ (prop.key): prop.value]) +// filter(ReplaceTokens, tokens: [ ('project.' + prop.key): prop.value]) +// } +// } +// } +//} +ext { + index = '1' + string = "gradleString" +} +ext.profile = (!project.hasProperty('profile') || !profile) ? 'dev' : profile +ext.springProfilesActive = System.properties['spring.profiles.active'] +sourceSets { + println("springProfilesActive:::::: $springProfilesActive") + println("\$profile:::::: $profile") + println("project.profile:::::: " + project.profile) + println("\$project.profile:::::: $project.profile") + println("\$project.ext.profile:::::: $project.ext.profile") + + main { + resources { + srcDirs "src/main/resources", "src/main/resources-env/${profile}" + } + } +} +tasks { + processResources { +// filesMatching('**/application.yml') { +// expand(project.properties) +// } + duplicatesStrategy = org.gradle.api.file.DuplicatesStrategy.EXCLUDE + } +} + + +tasks.named('test') { + outputs.dir snippetsDir + useJUnitPlatform() +} + +tasks.named('asciidoctor') { + inputs.dir snippetsDir + dependsOn test +} + +tasks.named('compileJava') { + inputs.files(tasks.named('processResources')) +} + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..249e583 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..ae04661 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..a69d9cb --- /dev/null +++ b/gradlew @@ -0,0 +1,240 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f127cfd --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,91 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/img.png b/img.png new file mode 100644 index 0000000..a9fc4a5 Binary files /dev/null and b/img.png differ diff --git a/libs/ojdbc6.jar b/libs/ojdbc6.jar new file mode 100644 index 0000000..b663cd2 Binary files /dev/null and b/libs/ojdbc6.jar differ diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..08490c8 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'ntri' diff --git a/src/main/java/cokr/xit/ntri/NtriApplication.java b/src/main/java/cokr/xit/ntri/NtriApplication.java new file mode 100644 index 0000000..b3c1180 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/NtriApplication.java @@ -0,0 +1,44 @@ +package cokr.xit.ntri; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.ApplicationPidFileWriter; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.ComponentScan; + +@Slf4j +@ComponentScan(basePackages = "cokr.xit") +@SpringBootApplication +public class NtriApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { +// SpringApplication.run(NtriApplication.class, args); + + + Long begin = System.currentTimeMillis(); + + // PID Setting ... + SpringApplication application = new SpringApplication(NtriApplication.class); + application.addListeners(new ApplicationPidFileWriter()); //PID(Process ID 작성) + application.run(args); + + + log.info("========================================================================================="); + log.info("========== NTRI Application load Complete :: active profiles - {} ==========", System.getProperty("spring.profiles.active")); + log.info("========================================================================================="); + + + Long end = System.currentTimeMillis(); + System.out.println("===================================================="); + System.out.println("기동 소요시간: " + (end - begin) + "ms"); + System.out.println("===================================================="); + + } + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(NtriApplication.class); + } +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/code/LinkRstCd.java b/src/main/java/cokr/xit/ntri/api/recv/code/LinkRstCd.java new file mode 100644 index 0000000..70e431a --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/code/LinkRstCd.java @@ -0,0 +1,27 @@ +package cokr.xit.ntri.api.recv.code; + +import cokr.xit.ntri.support.code.CodeMapperType; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 연계결과코드 + */ +@RequiredArgsConstructor +public enum LinkRstCd implements CodeMapperType { + + ok("정상", "000") + , internalFail("내부오류", "002"); + + + @Getter + private final String codeNm; + @Getter + private final String extCode; + + @Override + public String getCode() { + return this.name(); + } + +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/RecvBaseEntity.java b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvBaseEntity.java new file mode 100644 index 0000000..46b2a81 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvBaseEntity.java @@ -0,0 +1,48 @@ +package cokr.xit.ntri.api.recv.entity; + +import cokr.xit.ntri.api.recv.code.LinkRstCd; +import cokr.xit.ntri.support.entity.BaseEntity; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; + +import javax.persistence.Column; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.MappedSuperclass; + +@Getter +@Setter +@MappedSuperclass +@SuperBuilder +@NoArgsConstructor +public class RecvBaseEntity extends BaseEntity { + + @Setter + @Schema(required = false, title = "자치단체코드", example = " ", description = " ") + @Column(name = "rsp_sgb_cd", length = 7) + private String rspSgbCd; + + @Setter + @Schema(required = false, title = "연계대상코드", example = " ", description = " ") + @Column(name = "rsp_link_trgt_cd", length = 15) + private String rspLinkTrgtCd; + + @Setter + @Schema(required = false, title = "연계관리키", example = " ", description = " ") + @Column(name = "rsp_link_mng_key", length = 50) + private String rspLinkMngKey; + + @Setter + @Schema(required = false, title = "연계결과코드", example = " ", description = " ") + @Column(name = "rsp_link_rst_cd", length = 30) + @Enumerated(EnumType.STRING) + private LinkRstCd rspLinkRstCd; + + @Setter + @Schema(required = false, title = "연계결과메시지", example = " ", description = " ") + @Column(name = "rsp_link_rst_msg", length = 200) + private String rspLinkRstMsg; +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/RecvError.java b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvError.java new file mode 100644 index 0000000..0cb56b1 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvError.java @@ -0,0 +1,55 @@ +package cokr.xit.ntri.api.recv.entity; + +import cokr.xit.ntri.support.entity.BaseEntity; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +import javax.persistence.*; + +@Getter +@ToString +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(schema = "", name = "ntri_recv_error") +@Schema(name = "RecvError", title = "수신오류(실시간)", description = "세외수입시스템으로 수신한 데이터 처리 중 Exception이 발생한 데이터를 기록한다.") +public class RecvError extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", nullable = false) + private Long id; + + @Schema(required = false, title = "자치단체코드", example = " ", description = "행정표준코드관리시스템의 자치단체코드") + @Column(name = "sgb_cd", nullable = true) + private String sgbCd; + @Schema(required = false, title = "인터페이스ID", example = " ", description = "세외수입에서 정의한 연계 인터페이스ID") + @Column(name = "if_id", nullable = true) + private String ifId; + @Schema(required = false, title = "연계관리키", example = " ", description = "연계대상 기관에서 관리하는 유일키") + @Column(name = "link_mng_key", nullable = true) + private String linkMngKey; + @Schema(required = false, title = "연계대상코드", example = " ", description = "세외수입에서 부여한 15자리 코드 조합. format: 연계기관코드(7)+연계시스템코드(3)+연계일련번호(5)") + @Column(name = "link_trgt_cd", nullable = true) + private String linkTrgtCd; + @Schema(required = false, title = "header raw 데이터", example = " ", description = "") + @Column(name = "raw_header", nullable = true) + @Lob + private String rawDataHeader; + @Schema(required = false, title = "요청데이터", example = " ", description = "세외수입에서 전송한 데이터") + @Lob + @Column(name = "req_data") + private String reqData; + @Schema(required = false, title = "에러메시지", example = " ", description = "에러메시지") + @Column(name = "err_msg", nullable = true) + private String errMsg; + @Schema(required = false, title = "에러메시지 상세", example = " ", description = "Runtime Error 메시지") + @Lob + @Column(name = "err_detail", nullable = true) + private String errDetail; + +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/RecvLevyCancel.java b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvLevyCancel.java new file mode 100644 index 0000000..22e4850 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvLevyCancel.java @@ -0,0 +1,57 @@ +package cokr.xit.ntri.api.recv.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +import javax.persistence.*; + +@Getter +@ToString +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(schema = "", name = "ntri_recv_levy_cancel") +@Schema(name = "RecvLevyCancel", title = "부과취소정보(실시간)", description = "세외수입시스템으로 부과자료 연계 후 부과자료 삭제 시 삭제정보 실시간 제공(재 부과 연계시 부과연계관리키는 변경하여 제공)") +public class RecvLevyCancel extends RecvBaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", nullable = false) + private Long id; + + @Schema(required = false, title = "자치단체코드", example = " ", description = "행정표준코드관리시스템의 자치단체코드") + @Column(name = "sgb_cd", length = 7) + private String sgbCd; + @Schema(required = false, title = "연계관리키", example = " ", description = "연계대상 기관에서 관리하는 유일키") + @Column(name = "link_mng_key", length = 50) + private String linkMngKey; + @Schema(required = false, title = "과세번호", example = " ", description = "과세자료의 유일한 번호. 개별자료인 경우") + @Column(name = "taxn_no", length = 31) + private String taxnNo; + @Schema(required = false, title = "부과취소일자", example = " ", description = " ") + @Column(name = "lvy_rtrcn_ymd", length = 8) + private String lvyRtrcnYmd; + @Schema(required = false, title = "삭제사유내용", example = " ", description = " ") + @Column(name = "del_rsn_cn", length = 4000) + private String delRsnCn; + @Schema(required = false, title = "예비항목1", example = " ", description = " ") + @Column(name = "rsve_item1", length = 200) + private String rsveItem1; + @Schema(required = false, title = "예비항목2", example = " ", description = " ") + @Column(name = "rsve_item2", length = 200) + private String rsveItem2; + @Schema(required = false, title = "예비항목3", example = " ", description = " ") + @Column(name = "rsve_item3", length = 200) + private String rsveItem3; + @Schema(required = false, title = "예비항목4", example = " ", description = " ") + @Column(name = "rsve_item4", length = 200) + private String rsveItem4; + @Schema(required = false, title = "예비항목5", example = " ", description = " ") + @Column(name = "rsve_item5", length = 200) + private String rsveItem5; + +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/RecvLevyResult.java b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvLevyResult.java new file mode 100644 index 0000000..d05dd95 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvLevyResult.java @@ -0,0 +1,201 @@ +package cokr.xit.ntri.api.recv.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +import javax.persistence.*; + +@Getter +@ToString +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(schema = "", name = "ntri_recv_levy_result") +@Schema(name = "RecvLevyResult", title = "부과결과정보(실시간)", description = "세외수입시스템으로 부과자료 연계 후 결의처리 시 전자납부번호 및 가상계좌번호 실시간 제공") +public class RecvLevyResult extends RecvBaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", nullable = false) + private Long id; + + @Schema(required = false, title = "자치단체코드", example = " ", description = "행정표준코드관리시스템의 자치단체코드") + @Column(name = "sgb_cd", length = 7) + private String sgbCd; + @Schema(required = false, title = "연계관리키", example = " ", description = "연계대상 기관에서 관리하는 유일키") + @Column(name = "link_mng_key", length = 50) + private String linkMngKey; + @Schema(required = false, title = "과세번호", example = " ", description = "과세자료의 유일한 번호. 개별자료인 경우") + @Column(name = "taxn_no", length = 31) + private String taxnNo; + @Schema(required = false, title = "통합과세번호", example = " ", description = "과세자료(과세번호)의 통합관리번호. 통합자료인 경우") + @Column(name = "unty_taxn_no", length = 31) + private String untyTaxnNo; + @Schema(required = false, title = "부서코드", example = " ", description = "행정표준코드관리시스템의 부서코드") + @Column(name = "dpt_cd", length = 7) + private String dptCd; + @Schema(required = false, title = "특별회계사업코드", example = " ", description = " ") + @Column(name = "spcl_fis_biz_cd", length = 4) + private String spclFisBizCd; + @Schema(required = false, title = "회계연도", example = " ", description = " ") + @Column(name = "fyr", length = 4) + private String fyr; + @Schema(required = false, title = "회계구분코드", example = " ", description = "16:국세, 31:시도세, 41:시군구세, 51:특별회계시도세, 61:특별회계시군구세") + @Column(name = "act_se_cd", length = 2) + private String actSeCd; + @Schema(required = false, title = "대표세입과목코드", example = " ", description = " ") + @Column(name = "rprs_txm_cd", length = 6) + private String rprsTxmCd; + @Schema(required = false, title = "운영항목코드", example = " ", description = " ") + @Column(name = "oper_item_cd", length = 3) + private String operItemCd; + @Schema(required = false, title = "부과번호", example = " ", description = " ") + @Column(name = "lvy_no", length = 6) + private String lvyNo; + @Schema(required = false, title = "분납번호", example = " ", description = " ") + @Column(name = "itm_no", length = 2) + private String itmNo; + @Schema(required = false, title = "전자납부번호", example = " ", description = " ") + @Column(name = "epay_no", length = 19) + private String epayNo; + @Schema(required = false, title = "통합가상계좌은행명1", example = " ", description = " ") + @Column(name = "vtlac_bank_nm1", length = 100) + private String vtlacBankNm1; + @Schema(required = false, title = "통합가상계좌은행명2", example = " ", description = " ") + @Column(name = "vtlac_bank_nm2", length = 100) + private String vtlacBankNm2; + @Schema(required = false, title = "통합가상계좌은행명3", example = " ", description = " ") + @Column(name = "vtlac_bank_nm3", length = 100) + private String vtlacBankNm3; + @Schema(required = false, title = "통합가상계좌은행명4", example = " ", description = " ") + @Column(name = "vtlac_bank_nm4", length = 100) + private String vtlacBankNm4; + @Schema(required = false, title = "통합가상계좌은행명5", example = " ", description = " ") + @Column(name = "vtlac_bank_nm5", length = 100) + private String vtlacBankNm5; + @Schema(required = false, title = "통합가상계좌은행명6", example = " ", description = " ") + @Column(name = "vtlac_bank_nm6", length = 100) + private String vtlacBankNm6; + @Schema(required = false, title = "통합가상계좌은행명7", example = " ", description = " ") + @Column(name = "vtlac_bank_nm7", length = 100) + private String vtlacBankNm7; + @Schema(required = false, title = "통합가상계좌은행명8", example = " ", description = " ") + @Column(name = "vtlac_bank_nm8", length = 100) + private String vtlacBankNm8; + @Schema(required = false, title = "통합가상계좌은행명9", example = " ", description = " ") + @Column(name = "vtlac_bank_nm9", length = 100) + private String vtlacBankNm9; + @Schema(required = false, title = "통합가상계좌은행명10", example = " ", description = " ") + @Column(name = "vtlac_bank_nm10", length = 100) + private String vtlacBankNm10; + @Schema(required = false, title = "통합가상계좌은행명11", example = " ", description = " ") + @Column(name = "vtlac_bank_nm11", length = 100) + private String vtlacBankNm11; + @Schema(required = false, title = "통합가상계좌은행명12", example = " ", description = " ") + @Column(name = "vtlac_bank_nm12", length = 100) + private String vtlacBankNm12; + @Schema(required = false, title = "통합가상계좌은행명13", example = " ", description = " ") + @Column(name = "vtlac_bank_nm13", length = 100) + private String vtlacBankNm13; + @Schema(required = false, title = "통합가상계좌은행명14", example = " ", description = " ") + @Column(name = "vtlac_bank_nm14", length = 100) + private String vtlacBankNm14; + @Schema(required = false, title = "통합가상계좌은행명15", example = " ", description = " ") + @Column(name = "vtlac_bank_nm15", length = 100) + private String vtlacBankNm15; + @Schema(required = false, title = "통합가상계좌은행명16", example = " ", description = " ") + @Column(name = "vtlac_bank_nm16", length = 100) + private String vtlacBankNm16; + @Schema(required = false, title = "통합가상계좌은행명17", example = " ", description = " ") + @Column(name = "vtlac_bank_nm17", length = 100) + private String vtlacBankNm17; + @Schema(required = false, title = "통합가상계좌은행명18", example = " ", description = " ") + @Column(name = "vtlac_bank_nm18", length = 100) + private String vtlacBankNm18; + @Schema(required = false, title = "통합가상계좌은행명19", example = " ", description = " ") + @Column(name = "vtlac_bank_nm19", length = 100) + private String vtlacBankNm19; + @Schema(required = false, title = "통합가상계좌은행명20", example = " ", description = " ") + @Column(name = "vtlac_bank_nm20", length = 100) + private String vtlacBankNm20; + @Schema(required = false, title = "통합가상계좌번호1", example = " ", description = " ") + @Column(name = "vr_actno1", length = 20) + private String vrActno1; + @Schema(required = false, title = "통합가상계좌번호2", example = " ", description = " ") + @Column(name = "vr_actno2", length = 20) + private String vrActno2; + @Schema(required = false, title = "통합가상계좌번호3", example = " ", description = " ") + @Column(name = "vr_actno3", length = 20) + private String vrActno3; + @Schema(required = false, title = "통합가상계좌번호4", example = " ", description = " ") + @Column(name = "vr_actno4", length = 20) + private String vrActno4; + @Schema(required = false, title = "통합가상계좌번호5", example = " ", description = " ") + @Column(name = "vr_actno5", length = 20) + private String vrActno5; + @Schema(required = false, title = "통합가상계좌번호6", example = " ", description = " ") + @Column(name = "vr_actno6", length = 20) + private String vrActno6; + @Schema(required = false, title = "통합가상계좌번호7", example = " ", description = " ") + @Column(name = "vr_actno7", length = 20) + private String vrActno7; + @Schema(required = false, title = "통합가상계좌번호8", example = " ", description = " ") + @Column(name = "vr_actno8", length = 20) + private String vrActno8; + @Schema(required = false, title = "통합가상계좌번호9", example = " ", description = " ") + @Column(name = "vr_actno9", length = 20) + private String vrActno9; + @Schema(required = false, title = "통합가상계좌번호10", example = " ", description = " ") + @Column(name = "vr_actno10", length = 20) + private String vrActno10; + @Schema(required = false, title = "통합가상계좌번호11", example = " ", description = " ") + @Column(name = "vr_actno11", length = 20) + private String vrActno11; + @Schema(required = false, title = "통합가상계좌번호12", example = " ", description = " ") + @Column(name = "vr_actno12", length = 20) + private String vrActno12; + @Schema(required = false, title = "통합가상계좌번호13", example = " ", description = " ") + @Column(name = "vr_actno13", length = 20) + private String vrActno13; + @Schema(required = false, title = "통합가상계좌번호14", example = " ", description = " ") + @Column(name = "vr_actno14", length = 20) + private String vrActno14; + @Schema(required = false, title = "통합가상계좌번호15", example = " ", description = " ") + @Column(name = "vr_actno15", length = 20) + private String vrActno15; + @Schema(required = false, title = "통합가상계좌번호16", example = " ", description = " ") + @Column(name = "vr_actno16", length = 20) + private String vrActno16; + @Schema(required = false, title = "통합가상계좌번호17", example = " ", description = " ") + @Column(name = "vr_actno17", length = 20) + private String vrActno17; + @Schema(required = false, title = "통합가상계좌번호18", example = " ", description = " ") + @Column(name = "vr_actno18", length = 20) + private String vrActno18; + @Schema(required = false, title = "통합가상계좌번호19", example = " ", description = " ") + @Column(name = "vr_actno19", length = 20) + private String vrActno19; + @Schema(required = false, title = "통합가상계좌번호20", example = " ", description = " ") + @Column(name = "vr_actno20", length = 20) + private String vrActno20; + @Schema(required = false, title = "예비항목1", example = " ", description = " ") + @Column(name = "rsve_item1", length = 200) + private String rsveItem1; + @Schema(required = false, title = "예비항목2", example = " ", description = " ") + @Column(name = "rsve_item2", length = 200) + private String rsveItem2; + @Schema(required = false, title = "예비항목3", example = " ", description = " ") + @Column(name = "rsve_item3", length = 200) + private String rsveItem3; + @Schema(required = false, title = "예비항목4", example = " ", description = " ") + @Column(name = "rsve_item4", length = 200) + private String rsveItem4; + @Schema(required = false, title = "예비항목5", example = " ", description = " ") + @Column(name = "rsve_item5", length = 200) + private String rsveItem5; + +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/RecvRcivInfo.java b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvRcivInfo.java new file mode 100644 index 0000000..ae74085 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvRcivInfo.java @@ -0,0 +1,139 @@ +package cokr.xit.ntri.api.recv.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +import javax.persistence.*; + +@Getter +@ToString +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(schema = "", name = "ntri_recv_rciv_info") +@Schema(name = "RecvRcivInfo", title = "수납정보(실시간)", description = "세외수입시스템으로 부과자료 연계 후 수납처리 시 실시간 제공") +public class RecvRcivInfo extends RecvBaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", nullable = false) + private Long id; + + @Schema(required = false, title = "자치단체코드", example = " ", description = "행정표준코드관리시스템의 자치단체코드") + @Column(name = "sgb_cd", length = 7) + private String sgbCd; + @Schema(required = false, title = "자치단체명", example = " ", description = "자치단체코드의 명") + @Column(name = "sgb_nm", length = 60) + private String sgbNm; + @Schema(required = false, title = "연계관리키", example = " ", description = "연계대상 기관에서 관리하는 유일키") + @Column(name = "link_mng_key", length = 50) + private String linkMngKey; + @Schema(required = false, title = "과세번호", example = " ", description = "과세자료의 유일한 번호. 개별자료인 경우") + @Column(name = "taxn_no", length = 31) + private String taxnNo; + @Schema(required = false, title = "통합과세번호", example = " ", description = "과세자료(과세번호)의 통합관리번호. 통합자료인 경우") + @Column(name = "unty_taxn_no", length = 31) + private String untyTaxnNo; + @Schema(required = false, title = "부서코드", example = " ", description = "행정표준코드관리시스템의 부서코드") + @Column(name = "dpt_cd", length = 7) + private String dptCd; + @Schema(required = false, title = "부서명", example = " ", description = "행정표준코드관리시스템의 부서코드의 명") + @Column(name = "dpt_nm", length = 200) + private String dptNm; + @Schema(required = false, title = "특별회계사업코드", example = " ", description = " ") + @Column(name = "spcl_fis_biz_cd", length = 4) + private String spclFisBizCd; + @Schema(required = false, title = "특별회계사업명", example = " ", description = " ") + @Column(name = "spcl_fis_biz_nm", length = 100) + private String spclFisBizNm; + @Schema(required = false, title = "회계연도", example = " ", description = " ") + @Column(name = "fyr", length = 4) + private String fyr; + @Schema(required = false, title = "회계구분코드", example = " ", description = "16:국세, 31:시도세, 41:시군구세, 51:특별회계시도세, 61:특별회계시군구세") + @Column(name = "act_se_cd", length = 2) + private String actSeCd; + @Schema(required = false, title = "회계구분명", example = " ", description = " ") + @Column(name = "act_se_nm", length = 100) + private String actSeNm; + @Schema(required = false, title = "대표세입과목코드", example = " ", description = " ") + @Column(name = "rprs_txm_cd", length = 6) + private String rprsTxmCd; + @Schema(required = false, title = "대표세입과목명", example = " ", description = " ") + @Column(name = "rprs_txm_nm", length = 100) + private String rprsTxmNm; + @Schema(required = false, title = "운영항목코드", example = " ", description = " ") + @Column(name = "oper_item_cd", length = 3) + private String operItemCd; + @Schema(required = false, title = "운영항목명", example = " ", description = " ") + @Column(name = "oper_item_nm", length = 100) + private String operItemNm; + @Schema(required = false, title = "부과번호", example = " ", description = " ") + @Column(name = "lvy_no", length = 6) + private String lvyNo; + @Schema(required = false, title = "분납번호", example = " ", description = "제도에 따른 부과자료 분납순번 01~89, 일부납부 신청에 따른 부과자료 순번 90~99") + @Column(name = "itm_no", length = 2) + private String itmNo; + + + @Schema(required = false, title = "전자납부번호", example = " ", description = " ") + @Column(name = "epay_no", length = 19) + private String epayNo; + @Schema(required = false, title = "수납번호", example = " ", description = "수납순번") + @Column(name = "rcvmt_no", length = 2) + private String rcvmtNo; + @Schema(required = false, title = "수납구분코드", example = " ", description = "01:완납, 02:이중수납, 03:분납, 04:과납, 05:오납, 06:일부수납") + @Column(name = "rcvmt_se_cd", length = 2) + private String rcvmtSeCd; + @Schema(required = false, title = "수납구분명", example = " ", description = "수납구분코드명(일부납부, 완납 등)") + @Column(name = "rcvmt_se_nm", length = 100) + private String rcvmtSeNm; + @Schema(required = false, title = "수납일자", example = " ", description = " ") + @Column(name = "rcvmt_ymd", length = 8) + private String rcvmtYmd; + @Schema(required = false, title = "회계일자", example = " ", description = " ") + @Column(name = "act_ymd", length = 8) + private String actYmd; + @Schema(required = false, title = "이체일자", example = " ", description = " ") + @Column(name = "tsf_ymd", length = 8) + private String tsfYmd; + @Schema(required = false, title = "수납본세금액", example = " ", description = "수납본세") + @Column(name = "rcvmt_pct_amt", length = 15) + private String rcvmtPctAmt; + @Schema(required = false, title = "수납가산금액", example = " ", description = "수납가산금") + @Column(name = "rcvmt_adtn_amt", length = 15) + private String rcvmtAdtnAmt; + @Schema(required = false, title = "수납이자금액", example = " ", description = "수납이자") + @Column(name = "rcvmt_intr_amt", length = 15) + private String rcvmtIntrAmt; + @Schema(required = false, title = "은행명", example = " ", description = " ") + @Column(name = "bank_nm", length = 30) + private String bankNm; + @Schema(required = false, title = "수납유형코드", example = " ", description = "01:OCR수납, 02:수기수납, 03:계좌이체, 04:세입정정, 05:배당") + @Column(name = "rcvmt_ty_cd", length = 2) + private String rcvmtTyCd; + @Schema(required = false, title = "수납유형", example = " ", description = "납부매체정보(계좌이체, 신용카드결제, 가상계좌수납 등)") + @Column(name = "rcvmt_ty", length = 300) + private String rcvmtTy; + + + @Schema(required = false, title = "예비항목1", example = " ", description = " ") + @Column(name = "rsve_item1", length = 200) + private String rsveItem1; + @Schema(required = false, title = "예비항목2", example = " ", description = " ") + @Column(name = "rsve_item2", length = 200) + private String rsveItem2; + @Schema(required = false, title = "예비항목3", example = " ", description = " ") + @Column(name = "rsve_item3", length = 200) + private String rsveItem3; + @Schema(required = false, title = "예비항목4", example = " ", description = " ") + @Column(name = "rsve_item4", length = 200) + private String rsveItem4; + @Schema(required = false, title = "예비항목5", example = " ", description = " ") + @Column(name = "rsve_item5", length = 200) + private String rsveItem5; + +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/RecvRdcamtInfo.java b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvRdcamtInfo.java new file mode 100644 index 0000000..7a18ca3 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/RecvRdcamtInfo.java @@ -0,0 +1,116 @@ +package cokr.xit.ntri.api.recv.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +import javax.persistence.*; + +@Getter +@ToString +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(schema = "", name = "ntri_recv_rdcamt_info") +@Schema(name = "RecvRdcamtInfo", title = "감액정보(실시간)", description = "세외수입시스템으로 부과자료 연계 후 감액자료 발생 시 실시간 제공") +public class RecvRdcamtInfo extends RecvBaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", nullable = false) + private Long id; + + @Schema(required = false, title = "자치단체코드", example = " ", description = "행정표준코드관리시스템의 자치단체코드") + @Column(name = "sgb_cd", length = 7) + private String sgbCd; + @Schema(required = false, title = "자치단체명", example = " ", description = "자치단체코드의 명") + @Column(name = "sgb_nm", length = 60) + private String sgbNm; + @Schema(required = false, title = "연계관리키", example = " ", description = "연계대상 기관에서 관리하는 유일키") + @Column(name = "link_mng_key", length = 50) + private String linkMngKey; + @Schema(required = false, title = "과세번호", example = " ", description = "과세자료의 유일한 번호. 개별자료인 경우") + @Column(name = "taxn_no", length = 31) + private String taxnNo; + @Schema(required = false, title = "통합과세번호", example = " ", description = "과세자료(과세번호)의 통합관리번호. 통합자료인 경우") + @Column(name = "unty_taxn_no", length = 31) + private String untyTaxnNo; + @Schema(required = false, title = "부서코드", example = " ", description = "행정표준코드관리시스템의 부서코드") + @Column(name = "dpt_cd", length = 7) + private String dptCd; + @Schema(required = false, title = "부서명", example = " ", description = "행정표준코드관리시스템의 부서코드의 명") + @Column(name = "dpt_nm", length = 200) + private String dptNm; + @Schema(required = false, title = "특별회계사업코드", example = " ", description = " ") + @Column(name = "spcl_fis_biz_cd", length = 4) + private String spclFisBizCd; + @Schema(required = false, title = "특별회계사업명", example = " ", description = " ") + @Column(name = "spcl_fis_biz_nm", length = 100) + private String spclFisBizNm; + @Schema(required = false, title = "회계연도", example = " ", description = " ") + @Column(name = "fyr", length = 4) + private String fyr; + @Schema(required = false, title = "회계구분코드", example = " ", description = "16:국세, 31:시도세, 41:시군구세, 51:특별회계시도세, 61:특별회계시군구세") + @Column(name = "act_se_cd", length = 2) + private String actSeCd; + @Schema(required = false, title = "회계구분명", example = " ", description = " ") + @Column(name = "act_se_nm", length = 100) + private String actSeNm; + @Schema(required = false, title = "대표세입과목코드", example = " ", description = " ") + @Column(name = "rprs_txm_cd", length = 6) + private String rprsTxmCd; + @Schema(required = false, title = "대표세입과목명", example = " ", description = " ") + @Column(name = "rprs_txm_nm", length = 100) + private String rprsTxmNm; + @Schema(required = false, title = "운영항목코드", example = " ", description = " ") + @Column(name = "oper_item_cd", length = 3) + private String operItemCd; + @Schema(required = false, title = "운영항목명", example = " ", description = " ") + @Column(name = "oper_item_nm", length = 100) + private String operItemNm; + @Schema(required = false, title = "부과번호", example = " ", description = " ") + @Column(name = "lvy_no", length = 6) + private String lvyNo; + @Schema(required = false, title = "분납번호", example = " ", description = " ") + @Column(name = "itm_no", length = 2) + private String itmNo; + + @Schema(required = false, title = "감액일자", example = " ", description = " ") + @Column(name = "rdc_ymd", length = 8) + private String rdcYmd; + @Schema(required = false, title = "감액본세금액", example = " ", description = "감액금액") + @Column(name = "rdc_pct_amt", length = 15) + private String rdcPctAmt; + @Schema(required = false, title = "금액가산금액", example = " ", description = "감액가산금") + @Column(name = "rdc_adtn_amt", length = 15) + private String rdcAdtnAmt; + @Schema(required = false, title = "감액이자금액", example = " ", description = "감액이자") + @Column(name = "rdc_intr_amt", length = 15) + private String rdcIntrAmt; + @Schema(required = false, title = "감액금액", example = " ", description = "감액총금액") + @Column(name = "rdc_amt", length = 15) + private String rdcAmt; + @Schema(required = false, title = "감액사유내용", example = " ", description = "감액사유내용(세액오류감액, 행정기관착오 등") + @Column(name = "rdc_rsn_cn", length = 255) + private String rdcRsnCn; + + @Schema(required = false, title = "예비항목1", example = " ", description = " ") + @Column(name = "rsve_item1", length = 200) + private String rsveItem1; + @Schema(required = false, title = "예비항목2", example = " ", description = " ") + @Column(name = "rsve_item2", length = 200) + private String rsveItem2; + @Schema(required = false, title = "예비항목3", example = " ", description = " ") + @Column(name = "rsve_item3", length = 200) + private String rsveItem3; + @Schema(required = false, title = "예비항목4", example = " ", description = " ") + @Column(name = "rsve_item4", length = 200) + private String rsveItem4; + @Schema(required = false, title = "예비항목5", example = " ", description = " ") + @Column(name = "rsve_item5", length = 200) + private String rsveItem5; + +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvErrorRepository.java b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvErrorRepository.java new file mode 100644 index 0000000..a770dc1 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvErrorRepository.java @@ -0,0 +1,7 @@ +package cokr.xit.ntri.api.recv.entity.repository; + +import cokr.xit.ntri.api.recv.entity.RecvError; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RecvErrorRepository extends JpaRepository { +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvLevyCancelRepository.java b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvLevyCancelRepository.java new file mode 100644 index 0000000..ed638ae --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvLevyCancelRepository.java @@ -0,0 +1,7 @@ +package cokr.xit.ntri.api.recv.entity.repository; + +import cokr.xit.ntri.api.recv.entity.RecvLevyCancel; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RecvLevyCancelRepository extends JpaRepository { +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvLevyResultRepository.java b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvLevyResultRepository.java new file mode 100644 index 0000000..b5ab664 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvLevyResultRepository.java @@ -0,0 +1,7 @@ +package cokr.xit.ntri.api.recv.entity.repository; + +import cokr.xit.ntri.api.recv.entity.RecvLevyResult; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RecvLevyResultRepository extends JpaRepository { +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvRcivInfoRepository.java b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvRcivInfoRepository.java new file mode 100644 index 0000000..02a2ec4 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvRcivInfoRepository.java @@ -0,0 +1,7 @@ +package cokr.xit.ntri.api.recv.entity.repository; + +import cokr.xit.ntri.api.recv.entity.RecvRcivInfo; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RecvRcivInfoRepository extends JpaRepository { +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvRdcamtInfoRepository.java b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvRdcamtInfoRepository.java new file mode 100644 index 0000000..c43aeff --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/entity/repository/RecvRdcamtInfoRepository.java @@ -0,0 +1,7 @@ +package cokr.xit.ntri.api.recv.entity.repository; + +import cokr.xit.ntri.api.recv.entity.RecvRdcamtInfo; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RecvRdcamtInfoRepository extends JpaRepository { +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/model/RecvResponseVO.java b/src/main/java/cokr/xit/ntri/api/recv/model/RecvResponseVO.java new file mode 100644 index 0000000..5c2e9e9 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/model/RecvResponseVO.java @@ -0,0 +1,26 @@ +package cokr.xit.ntri.api.recv.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class RecvResponseVO { + + @Schema(required = false, title = "자치단체코드", example = " ", description = " ") + private String sgbCd; + + @Schema(required = false, title = "연계대상코드", example = " ", description = " ") + private String linkTrgtCd; + + @Schema(required = false, title = "연계관리키", example = " ", description = " ") + private String linkMngKey; + + @Schema(required = false, title = "연계결과코드", example = " ", description = " ") + private String linkRstCd; + + @Schema(required = false, title = "연계결과메시지", example = " ", description = " ") + private String linkRstMsg; +} + diff --git a/src/main/java/cokr/xit/ntri/api/recv/presentation/NtriRecvApi.java b/src/main/java/cokr/xit/ntri/api/recv/presentation/NtriRecvApi.java new file mode 100644 index 0000000..17875dd --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/presentation/NtriRecvApi.java @@ -0,0 +1,176 @@ +package cokr.xit.ntri.api.recv.presentation; + +import cokr.xit.ntri.api.recv.entity.repository.*; +import cokr.xit.ntri.api.recv.service.RecvApiSpec; +import cokr.xit.ntri.api.recv.service.impl.LevyCancel; +import cokr.xit.ntri.api.recv.service.impl.LevyResult; +import cokr.xit.ntri.api.recv.service.impl.RcivInfo; +import cokr.xit.ntri.api.recv.service.impl.RdcamtInfo; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@Slf4j +@RequiredArgsConstructor +@RestController +@Tag(name = "NtriRecvApi", description = "차세대 세외수입 개별시스템 연계") +public class NtriRecvApi { + @Value("${app.response.linkTrgtCd}") + private String LINK_TRGT_CD; + private final RecvErrorRepository recvErrorRepository; + + private final RecvLevyCancelRepository recvLevyCancelRepository; + private final RecvLevyResultRepository recvLevyResultRepository; + private final RecvRcivInfoRepository recvRcivInfoRepository; + private final RecvRdcamtInfoRepository recvRdcamtInfoRepository; + + + private ObjectMapper mapper = new ObjectMapper(); + + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Example..." + , summary = "부과결과정보 전송", description = "세외수입시스템 -> 개별시스템을 호출하여 데이터를 전송 한다." + , value = "{\"header\":{\"ifDate\":\"20210412103022\",\"ifMsgKey\":\"Z211103155123435-e7def4c1652a478e9c77525ab5b3ebda\",\"ifId\":\"ERR_Z000001DCP_1741000NIS_0001\",\"source\":\"3820000DCP\",\"target\":\"1741000NIS\",\"ifType\":\"S\",\"ifFormat\":\"J\",\"retName\":\"\",\"retCode\":\"200\"},\"body\":{\"reqVo\":[{\"registDt\":null,\"lastUpdtDt\":null,\"rspSgbCd\":null,\"rspLinkTrgtCd\":null,\"rspLinkMngKey\":null,\"rspLinkRstCd\":null,\"rspLinkRstMsg\":null,\"id\":null,\"sgbCd\":null,\"linkMngKey\":null,\"taxnNo\":null,\"untyTaxnNo\":null,\"dptCd\":null,\"spclFisBizCd\":null,\"fyr\":null,\"actSeCd\":null,\"rprsTxmCd\":null,\"operItemCd\":null,\"lvyNo\":null,\"itmNo\":null,\"epayNo\":null,\"vtlacBankNm1\":null,\"vtlacBankNm2\":null,\"vtlacBankNm3\":null,\"vtlacBankNm4\":null,\"vtlacBankNm5\":null,\"vtlacBankNm6\":null,\"vtlacBankNm7\":null,\"vtlacBankNm8\":null,\"vtlacBankNm9\":null,\"vtlacBankNm10\":null,\"vtlacBankNm11\":null,\"vtlacBankNm12\":null,\"vtlacBankNm13\":null,\"vtlacBankNm14\":null,\"vtlacBankNm15\":null,\"vtlacBankNm16\":null,\"vtlacBankNm17\":null,\"vtlacBankNm18\":null,\"vtlacBankNm19\":null,\"vtlacBankNm20\":null,\"vrActno1\":null,\"vrActno2\":null,\"vrActno3\":null,\"vrActno4\":null,\"vrActno5\":null,\"vrActno6\":null,\"vrActno7\":null,\"vrActno8\":null,\"vrActno9\":null,\"vrActno10\":null,\"vrActno11\":null,\"vrActno12\":null,\"vrActno13\":null,\"vrActno14\":null,\"vrActno15\":null,\"vrActno16\":null,\"vrActno17\":null,\"vrActno18\":null,\"vrActno19\":null,\"vrActno20\":null,\"rsveItem1\":null,\"rsveItem2\":null,\"rsveItem3\":null,\"rsveItem4\":null,\"rsveItem5\":null}]}}") + }) + }) + @PostMapping(value = "/recv/levy/result", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "부과결과정보(실시간)", description = "세외수입시스템으로 부과자료 연계 후 결의처리 시 전자납부번호 및 가상계좌번호 실시간 제공") + public ResponseEntity levyResult(@RequestBody String jParam) throws Exception { + //저장 + RecvApiSpec recv = LevyResult.builder() + .jpaRepository(recvLevyResultRepository) + .jParam(jParam) + .recvErrorRepository(recvErrorRepository) + .linkTrgtCd(LINK_TRGT_CD) + .build(); +// Map resultInfo = this.execute(recv, jParam); + recv.execute(); + Map resultInfo = (Map) recv.getResponse(); + + return new ResponseEntity(resultInfo, HttpStatus.OK); + } + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Example..." + , summary = "부과취소정보 전송", description = "세외수입시스템 -> 개별시스템을 호출하여 데이터를 전송 한다." + , value = "{\"header\":{\"ifDate\":\"20210412103022\",\"ifMsgKey\":\"Z211103155123435-e7def4c1652a478e9c77525ab5b3ebda\",\"ifId\":\"ERR_Z000001DCP_1741000NIS_0002\",\"source\":\"3820000DCP\",\"target\":\"1741000NIS\",\"ifType\":\"S\",\"ifFormat\":\"J\",\"retName\":\"\",\"retCode\":\"200\"},\"body\":{\"reqVo\":[{\"registDt\":null,\"lastUpdtDt\":null,\"rspSgbCd\":null,\"rspLinkTrgtCd\":null,\"rspLinkMngKey\":null,\"rspLinkRstCd\":null,\"rspLinkRstMsg\":null,\"id\":null,\"sgbCd\":null,\"linkMngKey\":null,\"taxnNo\":null,\"lvyRtrcnYmd\":null,\"delRsnCn\":null,\"rsveItem1\":null,\"rsveItem2\":null,\"rsveItem3\":null,\"rsveItem4\":null,\"rsveItem5\":null}]}}") + }) + }) + @PostMapping(value = "/recv/levy/cancel", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "부과취소정보(실시간)", description = "세외수입시스템으로 부과자료 연계 후 부과자료 삭제 시 삭제정보 실시간 제공(재 부과 연계시 부과연계관리키는 변경하여 제공)") + public ResponseEntity levyCancel(@RequestBody String jParam) throws Exception { + //저장 + RecvApiSpec recv = LevyCancel.builder() + .jpaRepository(recvLevyCancelRepository) + .jParam(jParam) + .recvErrorRepository(recvErrorRepository) + .linkTrgtCd(LINK_TRGT_CD) + .build(); +// Map resultInfo = this.execute(recv, jParam); + recv.execute(); + Map resultInfo = (Map) recv.getResponse(); + + return new ResponseEntity(resultInfo, HttpStatus.OK); + } + + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Example..." + , summary = "수납정보 전송", description = "세외수입시스템 -> 개별시스템을 호출하여 데이터를 전송 한다." + , value = "{\"header\":{\"ifDate\":\"20210412103022\",\"ifMsgKey\":\"Z211103155123435-e7def4c1652a478e9c77525ab5b3ebda\",\"ifId\":\"ERR_Z000001DCP_1741000NIS_0003\",\"source\":\"3820000DCP\",\"target\":\"1741000NIS\",\"ifType\":\"S\",\"ifFormat\":\"J\",\"retName\":\"\",\"retCode\":\"200\"},\"body\":{\"reqVo\":[{\"registDt\":null,\"lastUpdtDt\":null,\"rspSgbCd\":null,\"rspLinkTrgtCd\":null,\"rspLinkMngKey\":null,\"rspLinkRstCd\":null,\"rspLinkRstMsg\":null,\"id\":null,\"sgbCd\":null,\"sgbNm\":null,\"linkMngKey\":null,\"taxnNo\":null,\"untyTaxnNo\":null,\"dptCd\":null,\"dptNm\":null,\"spclFisBizCd\":null,\"spclFisBizNm\":null,\"fyr\":null,\"actSeCd\":null,\"actSeNm\":null,\"rprsTxmCd\":null,\"rprsTxmNm\":null,\"operItemCd\":null,\"operItemNm\":null,\"lvyNo\":null,\"itmNo\":null,\"epayNo\":null,\"rcvmtNo\":null,\"rcvmtSeCd\":null,\"rcvmtSeNm\":null,\"rcvmtYmd\":null,\"actYmd\":null,\"tsfYmd\":null,\"rcvmtPctAmt\":null,\"rcvmtAdtnAmt\":null,\"rcvmtIntrAmt\":null,\"bankNm\":null,\"rcvmtTyCd\":null,\"rcvmtTy\":null,\"rsveItem1\":null,\"rsveItem2\":null,\"rsveItem3\":null,\"rsveItem4\":null,\"rsveItem5\":null}]}}") + }) + }) + @PostMapping(value = "/recv/rciv/info", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "수납정보(실시간)", description = "세외수입시스템으로 부과자료 연계 후 수납처리 시 실시간 제공") + public ResponseEntity rcivInfo(@RequestBody String jParam) throws Exception { + //저장 + RecvApiSpec recv = RcivInfo.builder() + .jpaRepository(recvRcivInfoRepository) + .jParam(jParam) + .recvErrorRepository(recvErrorRepository) + .linkTrgtCd(LINK_TRGT_CD) + .build(); +// Map resultInfo = this.execute(recv, jParam); + recv.execute(); + Map resultInfo = (Map) recv.getResponse(); + + return new ResponseEntity(resultInfo, HttpStatus.OK); + } + + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Example..." + , summary = "감액정보 전송", description = "세외수입시스템 -> 개별시스템을 호출하여 데이터를 전송 한다." + , value = "{\"header\":{\"ifDate\":\"20210412103022\",\"ifMsgKey\":\"Z211103155123435-e7def4c1652a478e9c77525ab5b3ebda\",\"ifId\":\"ERR_Z000001DCP_1741000NIS_0004\",\"source\":\"3820000DCP\",\"target\":\"1741000NIS\",\"ifType\":\"S\",\"ifFormat\":\"J\",\"retName\":\"\",\"retCode\":\"200\"},\"body\":{\"reqVo\":[{\"registDt\":null,\"lastUpdtDt\":null,\"rspSgbCd\":null,\"rspLinkTrgtCd\":null,\"rspLinkMngKey\":null,\"rspLinkRstCd\":null,\"rspLinkRstMsg\":null,\"id\":null,\"sgbCd\":null,\"sgbNm\":null,\"linkMngKey\":null,\"taxnNo\":null,\"untyTaxnNo\":null,\"dptCd\":null,\"dptNm\":null,\"spclFisBizCd\":null,\"spclFisBizNm\":null,\"fyr\":null,\"actSeCd\":null,\"actSeNm\":null,\"rprsTxmCd\":null,\"rprsTxmNm\":null,\"operItemCd\":null,\"operItemNm\":null,\"lvyNo\":null,\"itmNo\":null,\"rdcYmd\":null,\"rdcPctAmt\":null,\"rdcAdtnAmt\":null,\"rdcIntrAmt\":null,\"rdcAmt\":null,\"rdcRsnCn\":null,\"rsveItem1\":null,\"rsveItem2\":null,\"rsveItem3\":null,\"rsveItem4\":null,\"rsveItem5\":null}]}}") + }) + }) + @PostMapping(value = "/recv/rdcamt/info", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "감액정보(실시간)", description = "세외수입시스템으로 부과자료 연계 후 감액자료 발생 시 실시간 제공") + public ResponseEntity rdcamtInfo(@RequestBody String jParam) throws Exception { + //저장 + RecvApiSpec recv = RdcamtInfo.builder() + .jpaRepository(recvRdcamtInfoRepository) + .jParam(jParam) + .recvErrorRepository(recvErrorRepository) + .linkTrgtCd(LINK_TRGT_CD) + .build(); +// Map resultInfo = this.execute(recv, jParam); + recv.execute(); + Map resultInfo = (Map) recv.getResponse(); + + return new ResponseEntity(resultInfo, HttpStatus.OK); + } + + private Map execute(RecvApiSpec recv, String jParam) { + Map resultInfo = null; + Map header = null; + Map body = null; + try { + //parsing + resultInfo = (Map) mapper.readValue(jParam, Map.class); + header = (Map) resultInfo.get("header"); + body = (Map) resultInfo.get("body"); + //excute + recv.execute(); + //result SET + header.put("retCode", "200"); + header.put("retName", "성공"); + body.put("resVo", recv.getResponse()); + resultInfo.put("header", header); + resultInfo.put("body", body); + } catch (JsonProcessingException e) { + if (header != null) { + header.put("retCode", "500"); + header.put("retName", "실패. 사유: Parameter Parsing Fail!! " + e.getMessage()); + resultInfo.put("header", header); + } + } catch (Exception e) { + if (header != null) { + header.put("retCode", "500"); + header.put("retName", "실패. 사유: " + e.getMessage()); + resultInfo.put("header", header); + } + } + + return resultInfo; + } +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/presentation/NtriTransferApi.java b/src/main/java/cokr/xit/ntri/api/recv/presentation/NtriTransferApi.java new file mode 100644 index 0000000..37dc970 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/presentation/NtriTransferApi.java @@ -0,0 +1,54 @@ +package cokr.xit.ntri.api.recv.presentation; + +import cokr.xit.ntri.core.config.IFConfig; +import cokr.xit.ntri.core.config.IFConfigManager; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Map; + +@Slf4j +@RequiredArgsConstructor +@RestController +@Tag(name = "NtriTransferApi", description = "차세대 세외수입 개별시스템 API 수신 경유") +public class NtriTransferApi { + + private final IFConfigManager ifConfigManager; + + @PostMapping(value = "/recv", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "수신경유", description = "세외수입으로 부터 수신에 대하여 Interface ID를 확인 후 URL을 분기한다.") + public void recvtransfer(@RequestBody Map param, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + + Map header = (Map) param.get("header"); + if (header == null) { + response.getWriter().println("{\"error_code\":\"INVALID_VALUE\", \"error_message\":\"not exists 'header' in param\"}"); + throw new RuntimeException("not exists 'header' in param"); + } + + String ifId = (String) header.get("ifId"); + if (ifId == null) { + response.getWriter().println("{\"error_code\":\"INVALID_VALUE\", \"error_message\":\"not exists 'ifId' in header\"}"); + throw new RuntimeException("not exists 'ifId' in header"); + } + + IFConfig ifConfig = ifConfigManager.getEnvironment().get(ifId); + if (ifConfig == null) { + response.getWriter().println("{\"error_code\":\"INVALID_REQUEST\", \"error_message\":\"not found IF!!\"}"); + throw new RuntimeException("not found IF!!"); + } + + RequestDispatcher rd = request.getRequestDispatcher(ifConfig.getUrl()); + rd.forward(request, response); + } +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/service/RecvApiSpec.java b/src/main/java/cokr/xit/ntri/api/recv/service/RecvApiSpec.java new file mode 100644 index 0000000..b40d996 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/service/RecvApiSpec.java @@ -0,0 +1,18 @@ +package cokr.xit.ntri.api.recv.service; + +import com.fasterxml.jackson.core.JsonProcessingException; + +public interface RecvApiSpec { + + void execute() throws Exception; + + void parsing() throws JsonProcessingException; + + void mapping(); + + void save(); + + + RT getResponse(); + +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/service/RecvApiSupport.java b/src/main/java/cokr/xit/ntri/api/recv/service/RecvApiSupport.java new file mode 100644 index 0000000..f0a6d75 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/service/RecvApiSupport.java @@ -0,0 +1,194 @@ +package cokr.xit.ntri.api.recv.service; + +import cokr.xit.ntri.api.recv.code.LinkRstCd; +import cokr.xit.ntri.api.recv.entity.RecvError; +import cokr.xit.ntri.api.recv.entity.repository.RecvErrorRepository; +import cokr.xit.ntri.api.recv.model.RecvResponseVO; +import cokr.xit.ntri.support.utils.CmmnUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.orm.jpa.JpaSystemException; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +public abstract class RecvApiSupport implements RecvApiSpec> { + protected final String jParam; + protected final JpaRepository jpaRepository; + private final RecvErrorRepository recvErrorRepository; + protected final String linkTrgtCd; + + protected ObjectMapper mapper = new ObjectMapper(); + private Map header; + private Map body; + private List datas; + private DATA data; + private E entity; + private RecvResponseVO recvResponseVO; + private String sgbCd; + private String linkMngKey; + + @Override + public void execute() throws Exception { + String phase = null; + List> fails = new ArrayList<>(); + try { + phase = "내부오류. 연계대상코드(linkTrgtCd) 미설정"; + if (linkTrgtCd == null || "".equals(linkTrgtCd) || " ".equals(linkTrgtCd) || "unknown".equals(linkTrgtCd)) + throw new RuntimeException(); + phase = "Parameter 파싱 실패"; + parsing(); + for (DATA data : datas) { + try { + this.data = data; + phase = "파싱 데이터 객체 매핑 실패"; + mapping(); + phase = "데이터 저장 실패"; + save(); + phase = "결과 저장 실패"; + this.entity = setResult(this.entity); + save(); + } catch (JpaSystemException e) { + Map fail = this.genFail(String.format("%s. 표준연계지침의 메시지전문구성 필드의 타입과 사이즈가 다를 경우 DB에 저장 할 수 없습니다.", phase), e); + fails.add(fail); + } catch (Exception e) { + Map fail = this.genFail(phase, e); + fails.add(fail); + Exception ex = new RuntimeException(phase, e); + this.entity = setResult(this.entity, ex); + save(); + } + } + + if (CmmnUtil.isEmpty(fails)) + this.setResponse(LinkRstCd.ok, LinkRstCd.ok.getCodeNm()); + else { + if (fails.size() == 1) + this.setResponse(LinkRstCd.internalFail, String.format("%s. [식별키 %s]", fails.get(0).get("errMsg"), fails.get(0).get("linkMngKey"))); + else + this.setResponse(LinkRstCd.internalFail, String.format("처리에 실패 했습니다. [식별키 %s] 외 %d 건", fails.get(0).get("linkMngKey"), fails.size() - 1)); + } + } catch (JsonProcessingException e) { + this.setResponse(LinkRstCd.internalFail, "처리에 실패 했습니다.", true, String.format("정상적인 요청전문이 아닙니다. %s", e.getMessage())); + } catch (Exception e) { + this.setResponse(LinkRstCd.internalFail, "처리에 실패 했습니다.", true, phase); + } finally { + if (fails.size() > 0) { + final String rawDataHeader = mapper.writeValueAsString(this.header); + recvErrorRepository.saveAll(fails.stream() + .map(fail -> RecvError.builder() + .sgbCd(fail.get("sgbCd")) + .ifId(this.header.get("ifId")) + .linkTrgtCd(this.linkTrgtCd) + .linkMngKey(fail.get("linkMngKey")) + .rawDataHeader(rawDataHeader) + .reqData(fail.get("reqData")) + .errMsg(fail.get("errMsg")) + .errDetail(fail.get("errDetail")) + .build()) + .collect(Collectors.toList()) + ); + } + } + } + + private Map genFail(String errMsg, Exception e) throws JsonProcessingException { + Map fail = new HashMap<>(); + fail.put("sgbCd", this.sgbCd); + fail.put("linkMngKey", this.linkMngKey); + fail.put("reqData", CmmnUtil.isEmpty(this.data) ? null : mapper.writeValueAsString(this.data)); + fail.put("errMsg", errMsg); + fail.put("errDetail", CmmnUtil.printStackTraceToString(e)); + return fail; + } + + protected abstract Map parsingHeader(String jParam) throws JsonProcessingException; + + protected abstract Map parsingBody(String jParam) throws JsonProcessingException; + + protected abstract List parsingData(Map body); + + @Override + public void parsing() throws JsonProcessingException { + String phase = ""; + try { + phase = "header parsing fail"; + this.header = parsingHeader(this.jParam); + if (this.header == null) throw new RuntimeException(); + phase = "body parsing fail"; + this.body = parsingBody(this.jParam); + if (this.body == null) throw new RuntimeException(); + phase = "data parsing fail"; + this.datas = parsingData(this.body); + if (this.datas == null) throw new RuntimeException(); + } catch (Exception e) { + throw new JsonMappingException(phase); + } + } + + + protected abstract E mapping(DATA m); + + @Override + public void mapping() { + this.entity = mapping(data); + this.sgbCd = getSgbCd(this.entity); + this.linkMngKey = getLinkMngKey(this.entity); + } + + protected abstract String getSgbCd(E e); + + protected abstract String getLinkMngKey(E e); + + @Override + public void save() { + this.jpaRepository.save(entity); + } + + protected abstract E setResult(E entity); + + protected abstract E setResult(E entity, Exception e); + + private void setResponse(LinkRstCd linkRstCd, String linkRstMsg) { + this.setResponse(linkRstCd, linkRstMsg, false, null); + } + + private void setResponse(LinkRstCd linkRstCd, String linkRstMsg, boolean hasException, String headerErrMsg) { + if (this.header == null) this.header = new HashMap<>(); + if (this.body == null) this.body = new HashMap<>(); + + if (hasException) { + this.header.put("retCode", "500"); + this.header.put("retName", headerErrMsg); + } else { + this.header.put("retCode", "200"); + this.header.put("retName", "성공"); + + } + + this.recvResponseVO = RecvResponseVO.builder() + .sgbCd(this.sgbCd) + .linkTrgtCd(this.linkTrgtCd) + .linkMngKey(this.linkMngKey) + .linkRstCd(linkRstCd.getExtCode()) + .linkRstMsg(linkRstMsg) + .build(); + } + + @Override + public Map getResponse() { + Map response = new HashMap<>(); + response.put("header", this.header); + this.body.put("resVo", this.recvResponseVO); + response.put("body", this.body); + return response; + } + +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/service/impl/LevyCancel.java b/src/main/java/cokr/xit/ntri/api/recv/service/impl/LevyCancel.java new file mode 100644 index 0000000..59445f1 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/service/impl/LevyCancel.java @@ -0,0 +1,84 @@ +package cokr.xit.ntri.api.recv.service.impl; + +import cokr.xit.ntri.api.recv.code.LinkRstCd; +import cokr.xit.ntri.api.recv.entity.RecvLevyCancel; +import cokr.xit.ntri.api.recv.entity.repository.RecvErrorRepository; +import cokr.xit.ntri.api.recv.service.RecvApiSupport; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.Builder; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Map; + +public class LevyCancel extends RecvApiSupport, RecvLevyCancel> { + + @Builder(builderClassName = "builder") + public LevyCancel(String jParam, JpaRepository jpaRepository, RecvErrorRepository recvErrorRepository, String linkTrgtCd) { + super(jParam, jpaRepository, recvErrorRepository, linkTrgtCd); + } + + @Override + protected Map parsingHeader(String jParam) throws JsonProcessingException { + return (Map) mapper.readValue(jParam, Map.class).get("header"); + } + + @Override + protected Map parsingBody(String jParam) throws JsonProcessingException { + return (Map) mapper.readValue(jParam, Map.class).get("body"); + } + + @Override + protected List> parsingData(Map body) { + return (List>) body.get("reqVo"); + } + + @Override + protected RecvLevyCancel mapping(Map m) { + return RecvLevyCancel.builder() + .sgbCd(m.get("sgbCd")) + .linkMngKey(m.get("linkMngKey")) + .taxnNo(m.get("taxnNo")) + .lvyRtrcnYmd(m.get("lvyRtrcnYmd")) + .delRsnCn(m.get("delRsnCn")) + .rsveItem1(m.get("rsveItem1")) + .rsveItem2(m.get("rsveItem2")) + .rsveItem3(m.get("rsveItem3")) + .rsveItem4(m.get("rsveItem4")) + .rsveItem5(m.get("rsveItem5")) + .build(); + } + + @Override + protected String getSgbCd(RecvLevyCancel recvLevyCancel) { + return recvLevyCancel.getSgbCd(); + } + + @Override + protected String getLinkMngKey(RecvLevyCancel recvLevyCancel) { + return recvLevyCancel.getLinkMngKey(); + } + + @Override + protected RecvLevyCancel setResult(RecvLevyCancel entity) { + entity.setRspSgbCd(entity.getSgbCd()); + entity.setRspLinkTrgtCd(super.linkTrgtCd); + entity.setRspLinkMngKey(entity.getLinkMngKey()); + entity.setRspLinkRstCd(LinkRstCd.ok); + entity.setRspLinkRstMsg(LinkRstCd.ok.getCodeNm()); + return entity; + } + + @Override + protected RecvLevyCancel setResult(RecvLevyCancel entity, Exception e) { + if (entity == null) + entity = RecvLevyCancel.builder().build(); + + entity.setRspSgbCd(entity.getSgbCd()); + entity.setRspLinkTrgtCd(super.linkTrgtCd); + entity.setRspLinkMngKey(entity.getLinkMngKey()); + entity.setRspLinkRstCd(LinkRstCd.internalFail); + entity.setRspLinkRstMsg(e.getMessage()); + return entity; + } +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/service/impl/LevyResult.java b/src/main/java/cokr/xit/ntri/api/recv/service/impl/LevyResult.java new file mode 100644 index 0000000..3467132 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/service/impl/LevyResult.java @@ -0,0 +1,132 @@ +package cokr.xit.ntri.api.recv.service.impl; + +import cokr.xit.ntri.api.recv.code.LinkRstCd; +import cokr.xit.ntri.api.recv.entity.RecvLevyResult; +import cokr.xit.ntri.api.recv.entity.repository.RecvErrorRepository; +import cokr.xit.ntri.api.recv.service.RecvApiSupport; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.Builder; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Map; + +public class LevyResult extends RecvApiSupport, RecvLevyResult> { + + @Builder(builderClassName = "builder") + public LevyResult(String jParam, JpaRepository jpaRepository, RecvErrorRepository recvErrorRepository, String linkTrgtCd) { + super(jParam, jpaRepository, recvErrorRepository, linkTrgtCd); + } + + @Override + protected Map parsingHeader(String jParam) throws JsonProcessingException { + return (Map) mapper.readValue(jParam, Map.class).get("header"); + } + + @Override + protected Map parsingBody(String jParam) throws JsonProcessingException { + return (Map) mapper.readValue(jParam, Map.class).get("body"); + } + + @Override + protected List> parsingData(Map body) { + return (List>) body.get("reqVo"); + } + + @Override + protected RecvLevyResult mapping(Map m) { + return RecvLevyResult.builder() + .sgbCd(m.get("sgbCd")) + .linkMngKey(m.get("linkMngKey")) + .taxnNo(m.get("taxnNo")) + .untyTaxnNo(m.get("untyTaxnNo")) + .dptCd(m.get("dptCd")) + .spclFisBizCd(m.get("spclFisBizCd")) + .fyr(m.get("fyr")) + .actSeCd(m.get("actSeCd")) + .rprsTxmCd(m.get("rprsTxmCd")) + .operItemCd(m.get("operItemCd")) + .lvyNo(m.get("lvyNo")) + .itmNo(m.get("itmNo")) + .epayNo(m.get("epayNo")) + .vtlacBankNm1(m.get("vtlacBankNm1")) + .vtlacBankNm2(m.get("vtlacBankNm2")) + .vtlacBankNm3(m.get("vtlacBankNm3")) + .vtlacBankNm4(m.get("vtlacBankNm4")) + .vtlacBankNm5(m.get("vtlacBankNm5")) + .vtlacBankNm6(m.get("vtlacBankNm6")) + .vtlacBankNm7(m.get("vtlacBankNm7")) + .vtlacBankNm8(m.get("vtlacBankNm8")) + .vtlacBankNm9(m.get("vtlacBankNm9")) + .vtlacBankNm10(m.get("vtlacBankNm10")) + .vtlacBankNm11(m.get("vtlacBankNm11")) + .vtlacBankNm12(m.get("vtlacBankNm12")) + .vtlacBankNm13(m.get("vtlacBankNm13")) + .vtlacBankNm14(m.get("vtlacBankNm14")) + .vtlacBankNm15(m.get("vtlacBankNm15")) + .vtlacBankNm16(m.get("vtlacBankNm16")) + .vtlacBankNm17(m.get("vtlacBankNm17")) + .vtlacBankNm18(m.get("vtlacBankNm18")) + .vtlacBankNm19(m.get("vtlacBankNm19")) + .vtlacBankNm20(m.get("vtlacBankNm20")) + .vrActno1(m.get("vrActno1")) + .vrActno2(m.get("vrActno2")) + .vrActno3(m.get("vrActno3")) + .vrActno4(m.get("vrActno4")) + .vrActno5(m.get("vrActno5")) + .vrActno6(m.get("vrActno6")) + .vrActno7(m.get("vrActno7")) + .vrActno8(m.get("vrActno8")) + .vrActno9(m.get("vrActno9")) + .vrActno10(m.get("vrActno10")) + .vrActno11(m.get("vrActno11")) + .vrActno12(m.get("vrActno12")) + .vrActno13(m.get("vrActno13")) + .vrActno14(m.get("vrActno14")) + .vrActno15(m.get("vrActno15")) + .vrActno16(m.get("vrActno16")) + .vrActno17(m.get("vrActno17")) + .vrActno18(m.get("vrActno18")) + .vrActno19(m.get("vrActno19")) + .vrActno20(m.get("vrActno20")) + .rsveItem1(m.get("rsveItem1")) + .rsveItem2(m.get("rsveItem2")) + .rsveItem3(m.get("rsveItem3")) + .rsveItem4(m.get("rsveItem4")) + .rsveItem5(m.get("rsveItem5")) + .build(); + } + + @Override + protected String getSgbCd(RecvLevyResult recvLevyResult) { + return recvLevyResult.getSgbCd(); + } + + @Override + protected String getLinkMngKey(RecvLevyResult recvLevyResult) { + return recvLevyResult.getLinkMngKey(); + } + + @Override + protected RecvLevyResult setResult(RecvLevyResult entity) { + entity.setRspSgbCd(entity.getSgbCd()); + entity.setRspLinkTrgtCd(super.linkTrgtCd); + entity.setRspLinkMngKey(entity.getLinkMngKey()); + entity.setRspLinkRstCd(LinkRstCd.ok); + entity.setRspLinkRstMsg(LinkRstCd.ok.getCodeNm()); + return entity; + } + + @Override + protected RecvLevyResult setResult(RecvLevyResult entity, Exception e) { + if (entity == null) + entity = RecvLevyResult.builder().build(); + + entity.setRspSgbCd(entity.getSgbCd()); + entity.setRspLinkTrgtCd(super.linkTrgtCd); + entity.setRspLinkMngKey(entity.getLinkMngKey()); + entity.setRspLinkRstCd(LinkRstCd.internalFail); + entity.setRspLinkRstMsg(e.getMessage()); + return entity; + } +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/service/impl/RcivInfo.java b/src/main/java/cokr/xit/ntri/api/recv/service/impl/RcivInfo.java new file mode 100644 index 0000000..1e60929 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/service/impl/RcivInfo.java @@ -0,0 +1,110 @@ +package cokr.xit.ntri.api.recv.service.impl; + +import cokr.xit.ntri.api.recv.code.LinkRstCd; +import cokr.xit.ntri.api.recv.entity.RecvRcivInfo; +import cokr.xit.ntri.api.recv.entity.repository.RecvErrorRepository; +import cokr.xit.ntri.api.recv.service.RecvApiSupport; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.Builder; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Map; + +public class RcivInfo extends RecvApiSupport, RecvRcivInfo> { + + @Builder(builderClassName = "builder") + public RcivInfo(String jParam, JpaRepository jpaRepository, RecvErrorRepository recvErrorRepository, String linkTrgtCd) { + super(jParam, jpaRepository, recvErrorRepository, linkTrgtCd); + } + + @Override + protected Map parsingHeader(String jParam) throws JsonProcessingException { + return (Map) mapper.readValue(jParam, Map.class).get("header"); + } + + @Override + protected Map parsingBody(String jParam) throws JsonProcessingException { + return (Map) mapper.readValue(jParam, Map.class).get("body"); + } + + @Override + protected List> parsingData(Map body) { + return (List>) body.get("reqVo"); + } + + @Override + protected RecvRcivInfo mapping(Map m) { + return RecvRcivInfo.builder() + .sgbCd(m.get("sgbCd")) + .sgbNm(m.get("sgbNm")) + .linkMngKey(m.get("linkMngKey")) + .taxnNo(m.get("taxnNo")) + .untyTaxnNo(m.get("untyTaxnNo")) + .dptCd(m.get("dptCd")) + .dptNm(m.get("dptNm")) + .spclFisBizCd(m.get("spclFisBizCd")) + .spclFisBizNm(m.get("spclFisBizNm")) + .fyr(m.get("fyr")) + .actSeCd(m.get("actSeCd")) + .actSeNm(m.get("actSeNm")) + .rprsTxmCd(m.get("rprsTxmCd")) + .rprsTxmNm(m.get("rprsTxmNm")) + .operItemCd(m.get("operItemCd")) + .operItemNm(m.get("operItemNm")) + .lvyNo(m.get("lvyNo")) + .itmNo(m.get("itmNo")) + .epayNo(m.get("epayNo")) + .rcvmtNo(m.get("rcvmtNo")) + .rcvmtSeCd(m.get("rcvmtSeCd")) + .rcvmtSeNm(m.get("rcvmtSeNm")) + .rcvmtYmd(m.get("rcvmtYmd")) + .actYmd(m.get("actYmd")) + .tsfYmd(m.get("tsfYmd")) + .rcvmtPctAmt(m.get("rcvmtPctAmt")) + .rcvmtAdtnAmt(m.get("rcvmtAdtnAmt")) + .rcvmtIntrAmt(m.get("rcvmtIntrAmt")) + .bankNm(m.get("bankNm")) + .rcvmtTyCd(m.get("rcvmtTyCd")) + .rcvmtTy(m.get("rcvmtTy")) + .rsveItem1(m.get("rsveItem1")) + .rsveItem2(m.get("rsveItem2")) + .rsveItem3(m.get("rsveItem3")) + .rsveItem4(m.get("rsveItem4")) + .rsveItem5(m.get("rsveItem5")) + .build(); + } + + @Override + protected String getSgbCd(RecvRcivInfo recvRcivInfo) { + return recvRcivInfo.getSgbCd(); + } + + @Override + protected String getLinkMngKey(RecvRcivInfo recvRcivInfo) { + return recvRcivInfo.getLinkMngKey(); + } + + @Override + protected RecvRcivInfo setResult(RecvRcivInfo entity) { + entity.setRspSgbCd(entity.getSgbCd()); + entity.setRspLinkTrgtCd(super.linkTrgtCd); + entity.setRspLinkMngKey(entity.getLinkMngKey()); + entity.setRspLinkRstCd(LinkRstCd.ok); + entity.setRspLinkRstMsg(LinkRstCd.ok.getCodeNm()); + return entity; + } + + @Override + protected RecvRcivInfo setResult(RecvRcivInfo entity, Exception e) { + if (entity == null) + entity = RecvRcivInfo.builder().build(); + + entity.setRspSgbCd(entity.getSgbCd()); + entity.setRspLinkTrgtCd(super.linkTrgtCd); + entity.setRspLinkMngKey(entity.getLinkMngKey()); + entity.setRspLinkRstCd(LinkRstCd.internalFail); + entity.setRspLinkRstMsg(e.getMessage()); + return entity; + } +} diff --git a/src/main/java/cokr/xit/ntri/api/recv/service/impl/RdcamtInfo.java b/src/main/java/cokr/xit/ntri/api/recv/service/impl/RdcamtInfo.java new file mode 100644 index 0000000..fc9c09b --- /dev/null +++ b/src/main/java/cokr/xit/ntri/api/recv/service/impl/RdcamtInfo.java @@ -0,0 +1,103 @@ +package cokr.xit.ntri.api.recv.service.impl; + +import cokr.xit.ntri.api.recv.code.LinkRstCd; +import cokr.xit.ntri.api.recv.entity.RecvRdcamtInfo; +import cokr.xit.ntri.api.recv.entity.repository.RecvErrorRepository; +import cokr.xit.ntri.api.recv.service.RecvApiSupport; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.Builder; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Map; + +public class RdcamtInfo extends RecvApiSupport, RecvRdcamtInfo> { + + @Builder(builderClassName = "builder") + public RdcamtInfo(String jParam, JpaRepository jpaRepository, RecvErrorRepository recvErrorRepository, String linkTrgtCd) { + super(jParam, jpaRepository, recvErrorRepository, linkTrgtCd); + } + + @Override + protected Map parsingHeader(String jParam) throws JsonProcessingException { + return (Map) mapper.readValue(jParam, Map.class).get("header"); + } + + @Override + protected Map parsingBody(String jParam) throws JsonProcessingException { + return (Map) mapper.readValue(jParam, Map.class).get("body"); + } + + @Override + protected List> parsingData(Map body) { + return (List>) body.get("reqVo"); + } + + @Override + protected RecvRdcamtInfo mapping(Map m) { + return RecvRdcamtInfo.builder() + .sgbCd(m.get("sgbCd")) + .sgbNm(m.get("sgbNm")) + .linkMngKey(m.get("linkMngKey")) + .taxnNo(m.get("taxnNo")) + .untyTaxnNo(m.get("untyTaxnNo")) + .dptCd(m.get("dptCd")) + .dptNm(m.get("dptNm")) + .spclFisBizCd(m.get("spclFisBizCd")) + .spclFisBizNm(m.get("spclFisBizNm")) + .fyr(m.get("fyr")) + .actSeCd(m.get("actSeCd")) + .actSeNm(m.get("actSeNm")) + .rprsTxmCd(m.get("rprsTxmCd")) + .rprsTxmNm(m.get("rprsTxmNm")) + .operItemCd(m.get("operItemCd")) + .operItemNm(m.get("operItemNm")) + .lvyNo(m.get("lvyNo")) + .itmNo(m.get("itmNo")) + .rdcYmd(m.get("rdcYmd")) + .rdcPctAmt(m.get("rdcPctAmt")) + .rdcAdtnAmt(m.get("rdcAdtnAmt")) + .rdcIntrAmt(m.get("rdcIntrAmt")) + .rdcAmt(m.get("rdcAmt")) + .rdcRsnCn(m.get("rdcRsnCn")) + .rsveItem1(m.get("rsveItem1")) + .rsveItem2(m.get("rsveItem2")) + .rsveItem3(m.get("rsveItem3")) + .rsveItem4(m.get("rsveItem4")) + .rsveItem5(m.get("rsveItem5")) + .build(); + } + + @Override + protected String getSgbCd(RecvRdcamtInfo recvRdcamtInfo) { + return recvRdcamtInfo.getSgbCd(); + } + + @Override + protected String getLinkMngKey(RecvRdcamtInfo recvRdcamtInfo) { + return recvRdcamtInfo.getLinkMngKey(); + } + + @Override + protected RecvRdcamtInfo setResult(RecvRdcamtInfo entity) { + entity.setRspSgbCd(entity.getSgbCd()); + entity.setRspLinkTrgtCd(super.linkTrgtCd); + entity.setRspLinkMngKey(entity.getLinkMngKey()); + entity.setRspLinkRstCd(LinkRstCd.ok); + entity.setRspLinkRstMsg(LinkRstCd.ok.getCodeNm()); + return entity; + } + + @Override + protected RecvRdcamtInfo setResult(RecvRdcamtInfo entity, Exception e) { + if (entity == null) + entity = RecvRdcamtInfo.builder().build(); + + entity.setRspSgbCd(entity.getSgbCd()); + entity.setRspLinkTrgtCd(super.linkTrgtCd); + entity.setRspLinkMngKey(entity.getLinkMngKey()); + entity.setRspLinkRstCd(LinkRstCd.internalFail); + entity.setRspLinkRstMsg(e.getMessage()); + return entity; + } +} diff --git a/src/main/java/cokr/xit/ntri/core/aop/AccessLogAspect.java b/src/main/java/cokr/xit/ntri/core/aop/AccessLogAspect.java new file mode 100644 index 0000000..b70b4c6 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/aop/AccessLogAspect.java @@ -0,0 +1,174 @@ +package cokr.xit.ntri.core.aop; + +import cokr.xit.ntri.core.aop.entity.AccessLog; +import cokr.xit.ntri.core.aop.entity.repository.AccessLogRepository; +import cokr.xit.ntri.support.utils.CmmnUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +@Component +@Aspect +@RequiredArgsConstructor +public class AccessLogAspect { + + private final AccessLogRepository accessLogRepository; + private final String ACCESS_TOKEN_NAME = "Authorization"; + + @Pointcut("execution(* cokr.xit..presentation.*Controller.*(..)) || execution(* cokr.xit..presentation.*Api.*(..))") + public void presentationLayer() { + } + + @Pointcut("execution(* cokr.xit..service.*Impl.*(..))") + public void serviceLayer() { + } + + @Pointcut("execution(* cokr.xit..domain.*Repository.*(..))") + public void persistenceLayer() { + } + + @Around("presentationLayer()") + public Object addLogOfRequestAndResponse(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { + long start = System.currentTimeMillis(); + + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); + + Object result = null; + AccessLog accessLog = null; + try { + accessLog = this.setRequestInfo(request); + accessLogRepository.save(accessLog); + + result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs()); + this.setResponseInfo(accessLog, result); + + + this.setResponseInfo(accessLog, result); + accessLogRepository.save(accessLog); + } catch (Exception e) { + log.error(String.format("[%s ERROR] : %s", "Unknown", e.getMessage()), e); + accessLog.setResponseFail(String.format("%s: %s", "Unknown", CmmnUtil.printStackTraceToString(e))); + accessLogRepository.save(accessLog); + + } finally { + long end = System.currentTimeMillis(); + log.info("Request: {} {}: {}. request Ajax: {} ({}ms)", request.getMethod(), request.getRequestURL(), paramMapToString(request.getParameterMap()), isAjax(request), end - start); + } + + + return result; + } + + + private String paramMapToString(Map paramMap) { + return paramMap.entrySet() + .stream() + .map(entry -> String.format("%s : %s", + entry.getKey(), Arrays.toString(entry.getValue()))) + .collect(Collectors.joining(", ")); + } + + private String paramMapToJsonString(Map paramMap) throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(paramMap); + } + + private String requestBodyToString(HttpServletRequest request) { + StringBuffer body = new StringBuffer(); + String line = null; + try { + BufferedReader reader = request.getReader(); + while ((line = reader.readLine()) != null) { + body.append(line); + } + } catch (Exception e) { + log.info("Error reading JSON string: " + e.toString()); + } + return body.toString(); + } + + @SuppressWarnings("deprecation") + private AccessLog setRequestInfo(HttpServletRequest request) throws JsonProcessingException { + String sessionId = request.getSession().getId(); + String param = null; + try { + param = this.requestBodyToString(request); + if (StringUtils.isEmpty(param)) //request body에 param 이 없으면.. + param = this.paramMapToJsonString(request.getParameterMap()); + } catch (Exception e) { + param = String.format("[요청 parameter 변환 실패]: %s", e.getMessage()); + } + + return AccessLog.reqBuilder() + .accessToken(request.getHeader(ACCESS_TOKEN_NAME)) + .sessionId(sessionId) + .ip(this.getClientIpAddr(request)) + .httpMethod(request.getMethod()) + .url(request.getRequestURL().toString()) + .uri(request.getRequestURI()) + .param(param) + .build(); + } + + private void setResponseInfo(AccessLog accessLog, Object result) { + String response = null; + if (result instanceof String) + response = (String) result; + else if (result instanceof List) + response = result.toString(); + else if (result instanceof Map) + response = result.toString(); + else + response = String.valueOf(result); + + accessLog.setResponseCompleted(response); + } + + private String getClientIpAddr(HttpServletRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + + return ip; + } + + private boolean isAjax(HttpServletRequest request) { + if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) + return true; + + return false; + + } + +} diff --git a/src/main/java/cokr/xit/ntri/core/aop/code/AccessStatusCd.java b/src/main/java/cokr/xit/ntri/core/aop/code/AccessStatusCd.java new file mode 100644 index 0000000..12177ec --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/aop/code/AccessStatusCd.java @@ -0,0 +1,24 @@ +package cokr.xit.ntri.core.aop.code; + +import cokr.xit.ntri.support.code.CodeMapperType; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum AccessStatusCd implements CodeMapperType { + + noAuth("권한없음") + ,req("요청완료") + ,cmplt("처리완료") + ,fail("처리실패") + ; + + @Getter + private final String codeNm; + + @Override + public String getCode() { + return this.name(); + } + +} diff --git a/src/main/java/cokr/xit/ntri/core/aop/entity/AccessLog.java b/src/main/java/cokr/xit/ntri/core/aop/entity/AccessLog.java new file mode 100644 index 0000000..00f735c --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/aop/entity/AccessLog.java @@ -0,0 +1,91 @@ +package cokr.xit.ntri.core.aop.entity; + +import cokr.xit.ntri.core.aop.code.AccessStatusCd; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Entity +@Getter +@RequiredArgsConstructor +@Table(name = "ntri_access_log", schema = "", catalog = "") +@Schema(name = "AccessLog", description = "접근 로그") +public class AccessLog { + + + /* ==================================== + * @GeneratedValue 어노테이션 전략 4가지 + * -.AUTO(default): JPA 구현체가 데이터베이스에 따라서 IDENTITIY/SEQUENCE/TABLE 중 자동으로 생성 전략 결정. + * -.IDENTITY: 기본키 생성을 데이터베이스에 위임. ex) MySQL의 경우 AUTO INCREMENT를 사용하여 기본키 생성.(MySQL, PostgresSQL, Server, DB2) + * -.SEQUENCE: 데이터베이스의 특별한 오브젝트 시퀀스를 사용하여 기본키를 생성.(Oracle, PostgresSQL, Db2, H2) + * -.TABLE: 데이터베이스에 키 생성 전용 테이블을 하나 만들고 이를 사용하여 기본키를 생성. + ==================================== */ + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long logId; //로그ID + + @Column(length = 2000) + private String accessToken; //엑세스토큰 + + private String sessionId; //세션 ID + + private String ip; //접근자 IP + + private String httpMethod; //요청 Method + + private String url; //요청 URL + + private String uri; //요청 URI + + @Lob + private String param; //요청 parameter(json format String) + @Lob + private String response; //응답 + + @Enumerated(EnumType.STRING) + private AccessStatusCd status; //상태 + + @Lob + private String errorMsg; //에러 메시지 + + @CreationTimestamp + private LocalDateTime startDt; //시작 일시 + + @UpdateTimestamp + private LocalDateTime endDt; //종료 일지 + + + @Builder(builderClassName = "reqBuilder", builderMethodName = "reqBuilder") + public AccessLog(String accessToken, String sessionId, String ip, String httpMethod, String url, String uri, String param) { + this.accessToken = accessToken; + this.sessionId = sessionId; + this.ip = ip; + this.httpMethod = httpMethod; + this.url = url; + this.uri = uri; + this.param = param; + this.status = AccessStatusCd.req; + } + + public void setResponseCompleted(String response) { + this.status = AccessStatusCd.cmplt; + this.response = response; + } + + public void setResponseFail(String errorMsg) { + this.status = AccessStatusCd.fail; + this.errorMsg = errorMsg; + } + + public void setResponseNoAuth(String errorMsg) { + this.status = AccessStatusCd.noAuth; + this.errorMsg = errorMsg; + } + +} diff --git a/src/main/java/cokr/xit/ntri/core/aop/entity/repository/AccessLogRepository.java b/src/main/java/cokr/xit/ntri/core/aop/entity/repository/AccessLogRepository.java new file mode 100644 index 0000000..173e39c --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/aop/entity/repository/AccessLogRepository.java @@ -0,0 +1,8 @@ +package cokr.xit.ntri.core.aop.entity.repository; + +import cokr.xit.ntri.core.aop.entity.AccessLog; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AccessLogRepository extends JpaRepository { + +} diff --git a/src/main/java/cokr/xit/ntri/core/config/IFConfig.java b/src/main/java/cokr/xit/ntri/core/config/IFConfig.java new file mode 100644 index 0000000..9961ca3 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/config/IFConfig.java @@ -0,0 +1,10 @@ +package cokr.xit.ntri.core.config; + +import lombok.Data; + +@Data +public class IFConfig { + private String name; + private String url; + +} diff --git a/src/main/java/cokr/xit/ntri/core/config/IFConfigManager.java b/src/main/java/cokr/xit/ntri/core/config/IFConfigManager.java new file mode 100644 index 0000000..164df89 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/config/IFConfigManager.java @@ -0,0 +1,17 @@ +package cokr.xit.ntri.core.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +@ConfigurationProperties("app.service.recv.interface") +@Getter +@Setter +public class IFConfigManager { + Map environment = new HashMap<>(); +} diff --git a/src/main/java/cokr/xit/ntri/core/config/JpaConfig.java b/src/main/java/cokr/xit/ntri/core/config/JpaConfig.java new file mode 100644 index 0000000..bee796a --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/config/JpaConfig.java @@ -0,0 +1,9 @@ +package cokr.xit.ntri.core.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@Configuration +@EnableJpaRepositories(basePackages = "cokr.xit.ntri") +public class JpaConfig { +} diff --git a/src/main/java/cokr/xit/ntri/core/config/WebConfig.java b/src/main/java/cokr/xit/ntri/core/config/WebConfig.java new file mode 100644 index 0000000..177e91f --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/config/WebConfig.java @@ -0,0 +1,27 @@ +package cokr.xit.ntri.core.config; + +import cokr.xit.ntri.core.filter.RequestWrapperFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.view.json.MappingJackson2JsonView; + +import java.util.Arrays; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Bean(name = "jsonView") + public MappingJackson2JsonView jsonView() { + return new MappingJackson2JsonView(); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Bean + public FilterRegistrationBean requestWrapperFilter() { + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new RequestWrapperFilter()); + filterRegistrationBean.setUrlPatterns(Arrays.asList("/*")); + return filterRegistrationBean; + } +} diff --git a/src/main/java/cokr/xit/ntri/core/filter/RequestWrapper.java b/src/main/java/cokr/xit/ntri/core/filter/RequestWrapper.java new file mode 100644 index 0000000..1e4ff83 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/filter/RequestWrapper.java @@ -0,0 +1,82 @@ +package cokr.xit.ntri.core.filter; + +import org.apache.commons.io.IOUtils; +import org.springframework.util.StringUtils; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +/** + *
      + *
    • 업무 그룹명: RequestWrapper 클래스
    • + *
    • 설 명: getInputStream() 오버라이딩하여 재사용이 가능하도록 한다.
    • + *
    • 작성일: 2021. 11. 30. 오전 11:22:09 + *
    + * + * @author 박민규 + */ +public class RequestWrapper extends HttpServletRequestWrapper { + private final Charset encoding; + private byte[] rawData; + + @SuppressWarnings("deprecation") + public RequestWrapper(HttpServletRequest request) throws IOException { + super(request); + String characterEncoding = request.getCharacterEncoding(); + if (StringUtils.isEmpty(characterEncoding)) { + characterEncoding = StandardCharsets.UTF_8.name(); + } + this.encoding = Charset.forName(characterEncoding); + + try { + InputStream inputStream = request.getInputStream(); //getInputStream()은 한번만 사용 가능. 이후 getInputStream 호출 시 "getInputStream() has already been called for this request" 오류 발생 + this.rawData = IOUtils.toByteArray(inputStream); //재사용이 가능하도록 byte[] rawData변수에 저장 후 getInputStream()를 오버라이딩하여 rawData 반환 + } catch (IOException e) { + throw e; + } + + } + + @Override + public ServletInputStream getInputStream() throws IOException { + final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.rawData); + ServletInputStream servletInputStream = new ServletInputStream() { + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + } + + public int read() throws IOException { + return byteArrayInputStream.read(); + } + }; + return servletInputStream; + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(this.getInputStream(), this.encoding)); + } + + @Override + public ServletRequest getRequest() { + return super.getRequest(); + } + + +} diff --git a/src/main/java/cokr/xit/ntri/core/filter/RequestWrapperFilter.java b/src/main/java/cokr/xit/ntri/core/filter/RequestWrapperFilter.java new file mode 100644 index 0000000..312cb41 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/core/filter/RequestWrapperFilter.java @@ -0,0 +1,17 @@ +package cokr.xit.ntri.core.filter; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +public class RequestWrapperFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + RequestWrapper readableRequestWrapper = new RequestWrapper((HttpServletRequest) request); //RequestWrapper 클래스로 wrapping + chain.doFilter(readableRequestWrapper, response); + } + +} diff --git a/src/main/java/cokr/xit/ntri/support/code/CodeMapperConfig.java b/src/main/java/cokr/xit/ntri/support/code/CodeMapperConfig.java new file mode 100644 index 0000000..9faed12 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/support/code/CodeMapperConfig.java @@ -0,0 +1,22 @@ +package cokr.xit.ntri.support.code; + +import cokr.xit.ntri.support.code.sample.SampleCd; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.LinkedHashMap; + +@Configuration +public class CodeMapperConfig { + + @Bean + public CodeMapperFactory codeMapperFactory() { + //CodeMapperFactory 초기화 + CodeMapperFactory codeMapperFactory = new CodeMapperFactory(new LinkedHashMap<>()); + + //Enum 추가 + codeMapperFactory.put(SampleCd.class); + + return codeMapperFactory; + } +} diff --git a/src/main/java/cokr/xit/ntri/support/code/CodeMapperFactory.java b/src/main/java/cokr/xit/ntri/support/code/CodeMapperFactory.java new file mode 100644 index 0000000..8ca80db --- /dev/null +++ b/src/main/java/cokr/xit/ntri/support/code/CodeMapperFactory.java @@ -0,0 +1,72 @@ +package cokr.xit.ntri.support.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Getter +@AllArgsConstructor +public class CodeMapperFactory { + + private Map> factory; + + /** + *
    메소드 설명: CodeMapperType을 구현한 Enum을 Factory에 추가하는 함수
    + * @param e void 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 10. 28. + */ + public void put(Class e) { + this.put(e.getSimpleName(), e); + } + /** + *
    메소드 설명: CodeMapperType을 구현한 Enum을 Factory에 추가하는 함수
    + * @param key + * @param e void 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 10. 28. + */ + public void put(String key, Class e) { + factory.put(key, this.toEnumValue(e)); + } + + /** + *
    메소드 설명: Factory에 추가된 Enum을 조회하는 함수
    + * @param e + * @return List 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 10. 28. + */ + public List get(Class e){ + return this.get(e.getSimpleName()); + } + /** + *
    메소드 설명: Factory에 추가된 Enum을 조회하는 함수
    + * @param key + * @return List 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 10. 28. + */ + public List get(String key){ + return factory.get(key); + } + + + /** + *
    메소드 설명: Enum의 내용들을 List로 변환하는 함수
    + * @param e + * @return List 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 10. 28. + */ + private List toEnumValue(Class e){ + return Arrays.stream(e.getEnumConstants()) //CodeMapperType을 구현한 열거형 상수(code/codeNm SET)코드를 + .map(CodeMapperValue::new) //CodeMapperValue 클래스로 생성하여 + .collect(Collectors.toList()); //List로 반환 + } + +} diff --git a/src/main/java/cokr/xit/ntri/support/code/CodeMapperType.java b/src/main/java/cokr/xit/ntri/support/code/CodeMapperType.java new file mode 100644 index 0000000..80f730e --- /dev/null +++ b/src/main/java/cokr/xit/ntri/support/code/CodeMapperType.java @@ -0,0 +1,20 @@ +package cokr.xit.ntri.support.code; + +public interface CodeMapperType { + /** + *
    메소드 설명: 해당 Enum의 코드를 조회하는 함수
    + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 10. 28. + */ + String getCode(); + + /** + *
    메소드 설명: 해당 Enum의 코드명을 조회하는 함수
    + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 10. 28. + */ + String getCodeNm(); + +} diff --git a/src/main/java/cokr/xit/ntri/support/code/CodeMapperValue.java b/src/main/java/cokr/xit/ntri/support/code/CodeMapperValue.java new file mode 100644 index 0000000..d45b707 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/support/code/CodeMapperValue.java @@ -0,0 +1,15 @@ +package cokr.xit.ntri.support.code; + +import lombok.Getter; + +@Getter +public class CodeMapperValue { + private String code; + private String codeNm; + + public CodeMapperValue(CodeMapperType codeMapperType) { + this.code = codeMapperType.getCode(); + this.codeNm = codeMapperType.getCodeNm(); + } + +} diff --git a/src/main/java/cokr/xit/ntri/support/code/sample/SampleCd.java b/src/main/java/cokr/xit/ntri/support/code/sample/SampleCd.java new file mode 100644 index 0000000..7bfa596 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/support/code/sample/SampleCd.java @@ -0,0 +1,22 @@ +package cokr.xit.ntri.support.code.sample; + +import cokr.xit.ntri.support.code.CodeMapperType; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum SampleCd implements CodeMapperType { + + CODE1("코드1") + ,CODE2("코드2"); + + + @Getter + private final String codeNm; + + @Override + public String getCode() { + return this.name(); + } + +} diff --git a/src/main/java/cokr/xit/ntri/support/code/sample/SampleCdUse.java b/src/main/java/cokr/xit/ntri/support/code/sample/SampleCdUse.java new file mode 100644 index 0000000..125cf91 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/support/code/sample/SampleCdUse.java @@ -0,0 +1,21 @@ +package cokr.xit.ntri.support.code.sample; + +import cokr.xit.ntri.support.code.CodeMapperFactory; +import cokr.xit.ntri.support.code.CodeMapperValue; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Slf4j +@Component +@RequiredArgsConstructor +public class SampleCdUse { + private final CodeMapperFactory codeMapperFactory; + + public void printSampleCds() { + List sampleCdList = codeMapperFactory.get("SampleCd"); + sampleCdList.stream().forEach(row -> log.info("{} {}", row.getCode(), row.getCodeNm())); + } +} diff --git a/src/main/java/cokr/xit/ntri/support/entity/BaseEntity.java b/src/main/java/cokr/xit/ntri/support/entity/BaseEntity.java new file mode 100644 index 0000000..2fd16f3 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/support/entity/BaseEntity.java @@ -0,0 +1,26 @@ +package cokr.xit.ntri.support.entity; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; + +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; +import java.time.LocalDateTime; + +@Getter +@MappedSuperclass +@SuperBuilder +@NoArgsConstructor +public class BaseEntity { + + @CreationTimestamp + @Column(name = "regist_dt", nullable = true) + private LocalDateTime registDt; + + @UpdateTimestamp + @Column(name = "last_updt_dt", nullable = true) + private LocalDateTime lastUpdtDt; +} diff --git a/src/main/java/cokr/xit/ntri/support/utils/CmmnUtil.java b/src/main/java/cokr/xit/ntri/support/utils/CmmnUtil.java new file mode 100644 index 0000000..2edcc02 --- /dev/null +++ b/src/main/java/cokr/xit/ntri/support/utils/CmmnUtil.java @@ -0,0 +1,128 @@ +package cokr.xit.ntri.support.utils; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; +import java.util.Map; + +@Slf4j +public class CmmnUtil { + +// private final static Logger logger = LoggerFactory.getLogger(CmmnUtil.class); + + + /** + *
    메소드 설명: 객체를 Json 포맷 String으로 반환 한다.
    + * + * @param obj + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 8. 5. + */ + public static String toJsonString(Object obj) { + return toJsonString(obj, JsonInclude.Include.ALWAYS); + } + + /** + *
    메소드 설명: 객체를 Json 포맷 String으로 반환 한다.
    + * + * @param obj + * @param type JsonInclude.Include + *
    +     *                                                 [type 종류]
    +     *                                                 	ALWAYS: 모든 필드
    +     *                                                 	NON_NULL: null제외
    +     *                                                  NON_ABSENT: null제외
    +     *                                                  NON_EMPTY: null/absent/isEmpty()==true/lenth==0 제외
    +     *                                                  NON_DEFAULT: empty는 제외된다.primitive 타입이 디폴트 값이면 제외한다. (int / Integer : 0 , boolean / Boolean : false 등)
    +     *                                                 
    + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 8. 5. + */ + public static String toJsonString(Object obj, JsonInclude.Include type) { + String result = null; + + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(type); //직렬화 타입 설정 + result = mapper.writeValueAsString(obj); + } catch (JsonProcessingException e) { +// throw new CustomException(RESP_CODE.INTERNAL_SERVER_ERROR, String.format("obj -> jsonString converting fail:: %s", e.getMessage())); + throw new RuntimeException(String.format("obj -> jsonString converting fail:: %s", e.getMessage()), e); + } + + return result; + } + + /** + *
    메소드 설명: jsonString을 Object로 반환한다
    + * + * @param clz + * @param jsonStr + * @return Object 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 12. 23. + */ + public static Object jsonStringtoObj(Class clz, String jsonStr) { + Object result = null; + + try { + ObjectMapper mapper = new ObjectMapper(); + result = mapper.readValue(jsonStr, clz.getClass()); + } catch (JsonProcessingException e) { + throw new RuntimeException(String.format("jsonString -> obj converting fail:: %s", e.getMessage()), e); + } + + return result; + } + + public static boolean isEmpty(Object obj) { + if (obj == null) return true; + if ((obj instanceof String) && (((String) obj).trim().length() == 0)) { + return true; + } + if (obj instanceof Map) { + return ((Map) obj).isEmpty(); + } + if (obj instanceof Map) { + return ((Map) obj).isEmpty(); + } + if (obj instanceof List) { + return ((List) obj).isEmpty(); + } + if (obj instanceof Object[]) { + return (((Object[]) obj).length == 0); + } + + return false; + } + + + public static String getServerUrl() { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); + + return String.format("%s://%s:%s", request.getScheme(), request.getServerName(), request.getServerPort()); + } + + public static String printStackTraceToString(Exception e) { + try { + StringWriter errors = new StringWriter(); + e.printStackTrace(new PrintWriter(errors)); + + return errors.toString(); + } catch (Exception ex) { + return "printStackTrace 변환에 실패 했습니다. " + ex.getMessage(); + } + } + + +} diff --git a/src/main/resources-env/dev/application-dev.yml b/src/main/resources-env/dev/application-dev.yml new file mode 100644 index 0000000..7b7ae43 --- /dev/null +++ b/src/main/resources-env/dev/application-dev.yml @@ -0,0 +1,82 @@ +app: + name: ntri + +#================= +# Server +#================= +server: + port: ${app.server.port:18080} + error: + include-exception: true #?? ??? Exception ?? ?? + include-stacktrace: never #?? ??? stacktrace ?? ?? + path: '/error' #http://~/error ?? + whitelabel: + enabled: true #?? ?? ??? ????? ??? ?? ??? ?? ?? + servlet: + context-path: / + +spring: + config: + activate: + on-profile: dev + # =================================================================================================================================== + # Procsss ID + # =================================================================================================================================== + pid: + file: ${app.name}.pid + # =================================================================================================================================== + # Database + # =================================================================================================================================== + sql: + init: + continue-on-error: false # ???? ? SQL ?? ?? ? ???? ?? + jpa: + database-platform: org.hibernate.dialect.Oracle10gDialect + hibernate: + ddl-auto: update # create / create-drop / update / validate / none + properties: + hibernate: + format_sql: true + use_sql_comments: true + show-sql: true + datasource: + driver-class-name: oracle.jdbc.OracleDriver + url: jdbc:oracle:thin:@211.119.124.117:1521:ora11g + username: xit_traffic + password: traffic5 + hikari: + auto-commit: false + minimum-idle: 10 + maximum-pool-size: 50 + connection-test-query: SELECT 1 FROM DUAL + transaction-isolation: TRANSACTION_READ_COMMITTED + pool-name: pool-${app.name} + hikari: + driver-class-name: ${spring.datasource.driver-class-name} + jdbc-url: ${spring.datasource.url} + username: ${spring.datasource.username} + password: ${spring.datasource.password} + + + + + +# =================================================================================================================================== +# Logging +# =================================================================================================================================== +logging: + charset: + console: utf-8 + file: utf-8 + level: + root: info + exception-conversion-word: '%wEx' + pattern: + console: '%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(${LOG_LEVEL_PATTERN:-%5p}){green} %clr([%18thread]){magenta} %clr(%-40.40logger{39}%line){cyan} %clr(: %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}){faint}' + file: + name: ./logs/${app.name}/logback.log + logback: + rollingpolicy: + file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}-%i.log + max-history: 30 #???? + max-file-size: 100MB #???? \ No newline at end of file diff --git a/src/main/resources-env/prod/application-prod.yml b/src/main/resources-env/prod/application-prod.yml new file mode 100644 index 0000000..2b69a6f --- /dev/null +++ b/src/main/resources-env/prod/application-prod.yml @@ -0,0 +1,124 @@ +app: + name: ntri + service: + recv: + interface: + environment: + ERR_1741000NIS_Z000001LGE_0001 : + name: '부과결과정보(실시간)' + url: '/recv/levy/result' + ERR_1741000NIS_Z000001LGE_0002: + name: '부과취소정보(실시간)' + url: '/recv/levy/cancel' + ERR_1741000NIS_Z000001LGE_0003 : + name: '수납정보(실시간)' + url: '/recv/rciv/info' + ERR_1741000NIS_Z000001LGE_0004 : + name: '감액정보(실시간)' + url: '/recv/rdcamt/info' + +#================= +# Server +#================= +server: + port: ${app.server.port:18080} + error: + include-exception: true #?? ??? Exception ?? ?? + include-stacktrace: never #?? ??? stacktrace ?? ?? + path: '/error' #http://~/error ?? + whitelabel: + enabled: true #?? ?? ??? ????? ??? ?? ??? ?? ?? + servlet: + context-path: / + #==================================================================== + # SSL + # -.Ref Site + # : OpenSSL Download(https://sourceforge.net/projects/openssl) + # : Generate SSL Cert(https://deeplify.dev/back-end/spring/tomcat-openssl) + # -.Command + # 1. openssl req -config ./openssl.cnf -x509 -sha256 -nodes -newkey rsa:2048 -keyout private.key -out public.pem -days 3650 + # 2. openssl pkcs12 -export -inKey private.key -in public.pem -name alias_name -out certificate.p12 + # -.Command-2 + # 1.서버개인키(private key) 생성 + # : openssl genrsa -out server.key 2048 //2048비트 길이의 개인키 생성 + # 2.인증서 세부정보 파일 생성, "-config" 옵션은 생략가능 + # : openssl req -new -key server.key -out server.csr -config ./openssl.cnf //openssl.cnf 를 참조하여 인증서신청서 생성 + # 3.서버인증서 생성 + # : openssl req -new -x509 -days 3650 -in server.csr -key server.key -out server.crt //서버인증서 발급 + #==================================================================== + ssl: + enabled: ${app.ssl.enabled:true} + #key-alias: ${app.ssl.key-alias:alias_name} + #key-store: ${app.ssl.key-store:classpath} + #key-store-type: ${app.ssl.key-store-type} + #key-store-password: ${app.ssl.key-store-password} + certificate-private-key: ${app.ssl.private-key} + certificate: ${app.ssl.cert} + +spring: + config: + activate: + on-profile: prod + # =================================================================================================================================== + # Procsss ID + # =================================================================================================================================== + pid: + file: ${app.name}.pid + # =================================================================================================================================== + # Database + # =================================================================================================================================== + sql: + init: + continue-on-error: false # ???? ? SQL ?? ?? ? ???? ?? + jpa: + # Oracle: Oracle10gDialect, Maria: MariaDB106Dialect, Mysql: MySQL5InnoDBDialect + database-platform: org.hibernate.dialect.${app.datasource.platform:Oracle10gDialect} + hibernate: + ddl-auto: update # create / create-drop / update / validate / none + properties: + hibernate: + format_sql: true + use_sql_comments: true + show-sql: false + datasource: + driver-class-name: ${app.datasource.driver:oracle.jdbc.OracleDriver} +# url: jdbc:oracle:thin:@${app.datasource.ip:211.119.124.117}:${app.datasource.port:1521}:${app.datasource.sid:ora11g} + url: ${app.datasource.url:'jdbc:oracle:thin:@211.119.124.117:1521:ora11g'} + username: ${app.datasource.username:xit_traffic} + password: ${app.datasource.password:traffic5} + hikari: + auto-commit: false + minimum-idle: 10 + maximum-pool-size: 50 + connection-test-query: SELECT 1 FROM DUAL + transaction-isolation: TRANSACTION_READ_COMMITTED + pool-name: pool-${app.name} + hikari: + driver-class-name: ${spring.datasource.driver-class-name} + jdbc-url: ${spring.datasource.url} + username: ${spring.datasource.username} + password: ${spring.datasource.password} + + + + + +# =================================================================================================================================== +# Logging +# =================================================================================================================================== +logging: + charset: + console: utf-8 + file: utf-8 + level: + root: info + exception-conversion-word: '%wEx' + pattern: + console: '%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(${LOG_LEVEL_PATTERN:-%5p}){green} %clr([%18thread]){magenta} %clr(%-40.40logger{39}%line){cyan} %clr(: %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}){faint}' + file: + name: ./logs/${app.name}/logback.log + logback: + rollingpolicy: + file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}-%i.log + max-history: 30 #???? + max-file-size: 100MB #???? diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..e49c0cc --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,136 @@ +app: + name: ntri + response: + linkTrgtCd: ${app.resp.linkTrgtCd:unknown} + service: + recv: + interface: + environment: + ERR_Z000001DCP_1741000NIS_0001 : + name: '부과결과정보(실시간)' + url: '/recv/levy/result' + ERR_Z000001DCP_1741000NIS_0002: + name: '부과취소정보(실시간)' + url: '/recv/levy/cancel' + ERR_Z000001DCP_1741000NIS_0003 : + name: '수납정보(실시간)' + url: '/recv/rciv/info' + ERR_Z000001DCP_1741000NIS_0004 : + name: '감액정보(실시간)' + url: '/recv/rdcamt/info' + +#================= +# Server +#================= +server: + port: 18080 + error: + include-exception: true #?? ??? Exception ?? ?? + include-stacktrace: never #?? ??? stacktrace ?? ?? + path: '/error' #http://~/error ?? + whitelabel: + enabled: true #?? ?? ??? ????? ??? ?? ??? ?? ?? + servlet: + context-path: / + +spring: + profiles: +# active: '@spring.profiles.active@' +# active: ${spring.profiles.active} +# active: dev +# active: ${ext.string} + active: '@springProfilesActive@' + # =================================================================================================================================== + # Procsss ID + # =================================================================================================================================== + pid: + file: ${app.name}.pid + # =================================================================================================================================== + # Database + # =================================================================================================================================== + sql: + init: + continue-on-error: false # ???? ? SQL ?? ?? ? ???? ?? + jpa: + database-platform: org.hibernate.dialect.Oracle10gDialect + generate-ddl: false + hibernate: + ddl-auto: update # create / create-drop / update / validate / none + properties: + hibernate: + format_sql: true + use_sql_comments: true + show-sql: true + datasource: + driver-class-name: oracle.jdbc.OracleDriver + url: jdbc:oracle:thin:@211.119.124.117:1521:ora11g + username: xit_traffic + password: traffic5 + hikari: + auto-commit: false + minimum-idle: 10 + maximum-pool-size: 50 + connection-test-query: SELECT 1 FROM DUAL + transaction-isolation: TRANSACTION_READ_COMMITTED + pool-name: pool-${app.name} + # data-source-properties: + # rewriteBatchedStatments: true #???? insert ??? ??? ?? + hikari: + driver-class-name: ${spring.datasource.driver-class-name} + jdbc-url: ${spring.datasource.url} + username: ${spring.datasource.username} + password: ${spring.datasource.password} + + + + + +# =================================================================================================================================== +# Logging +# =================================================================================================================================== +logging: + charset: + console: utf-8 + file: utf-8 + level: + root: info +# '[org.hibernate.type.descriptor.sql]': trace #jpa "?" ??(binding ????) ?? + # '[org.springframework.orm.jpa]': debug + # '[org.springframework.transaction]': debug + # '[org.springframework.transaction.interceptor]': trace + # '[org.springframework.jdbc.core]': off + # '[org.springframework.orm]': off + # '[org.springframework.orm.hibernate5]': off + # '[com.p6spy.engine.logging]': off + # '[com.p6spy]': off + # '[org.hibernate]': off + # '[org.hibernate.sql]': off + # '[org.hibernate.jpa]': off + exception-conversion-word: '%wEx' + pattern: + console: '%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(${LOG_LEVEL_PATTERN:-%5p}){green} %clr([%18thread]){magenta} %clr(%-40.40logger{39}%line){cyan} %clr(: %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}){faint}' + file: + name: ./logs/${app.name}/logback.log + logback: + rollingpolicy: + file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}-%i.log + max-history: 30 #???? + max-file-size: 100MB #???? + # '[org.hibernate.type.descriptor.sql]': trace + # '[org.springframework]': debug + # '[org.hibernate]': info + + + +# =================================================================================================================================== +# Springdoc +# =================================================================================================================================== +springdoc: + swagger-ui: + path: /swagger-ui.html + group-configs: + - group: 실시간 수신 + paths-to-match: + - /recv/** + + diff --git a/src/main/resources/ssl/bin/conf/openssl-sample.cnf b/src/main/resources/ssl/bin/conf/openssl-sample.cnf new file mode 100644 index 0000000..736c305 --- /dev/null +++ b/src/main/resources/ssl/bin/conf/openssl-sample.cnf @@ -0,0 +1,36 @@ +[ req ] +default_bits = 2048 +default_md = sha1 +default_keyfile = private.key +distinguished_name = req_distinguished_name +extensions = v3_ca +req_extensions = v3_ca + +[ v3_ca ] +basicConstraints = critical, CA:TRUE, pathlen:0 +subjectKeyIdentifier = hash +##authorityKeyIdentifier = keyid:always, issuer:always +keyUsage = keyCertSign, cRLSign +nsCertType = sslCA, emailCA, objCA +[req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = KR +countryName_min = 2 +countryName_max = 2 + +# 회사명 입력 +organizationName = Organization Name (eg, company) +organizationName_default = XIT Co. + +# 부서 입력 +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = Tech Support Team + +# SSL 서비스할 domain 명 입력 +commonName = Common Name (eg, your name or your servers hostname) +#commonName_default = indienote Self Signed CA +commonName_default = www.xit-ntri.co.kr +commonName_max = 64 + +# 이메일주소 +emailAddress_default = minkyu1128@xit.co.kr \ No newline at end of file diff --git a/src/test/java/cokr/xit/ntri/Example.java b/src/test/java/cokr/xit/ntri/Example.java new file mode 100644 index 0000000..85a5a78 --- /dev/null +++ b/src/test/java/cokr/xit/ntri/Example.java @@ -0,0 +1,60 @@ +package cokr.xit.ntri; + +import cokr.xit.ntri.api.recv.entity.RecvLevyCancel; +import cokr.xit.ntri.api.recv.entity.RecvLevyResult; +import cokr.xit.ntri.api.recv.entity.RecvRcivInfo; +import cokr.xit.ntri.api.recv.entity.RecvRdcamtInfo; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + + +public class Example { + + @Test + public void toJsonString() throws JsonProcessingException { + RecvLevyCancel recvLevyCancel = RecvLevyCancel.builder().build(); + RecvLevyResult recvLevyResult = RecvLevyResult.builder().build(); + RecvRcivInfo rcivInfo = RecvRcivInfo.builder().build(); + RecvRdcamtInfo recvRdcamtInfo = RecvRdcamtInfo.builder().build(); + + ObjectMapper mapper = new ObjectMapper(); + System.out.println(mapper.writeValueAsString(recvLevyCancel)); + System.out.println(mapper.writeValueAsString(recvLevyResult)); + System.out.println(mapper.writeValueAsString(rcivInfo)); + System.out.println(mapper.writeValueAsString(recvRdcamtInfo)); + } + + + @Test + public void staticField() { + ExampleVO vo1 = new ExampleVO(); + ExampleVO vo2 = new ExampleVO(); + + System.out.println("=========================================="); + System.out.println("Test - static field getter/setter ( setter 를 호출하여 static 필드에 값 설정 )"); + System.out.println("=========================================="); + vo1.setStaticQuery("select * from dual"); + System.out.println("vo1.staticQuery = " + vo1.getStaticQuery()); + System.out.println("vo2.staticQuery = " + vo2.getStaticQuery()); + System.out.println("ExampleVO.staticQuery = " + ExampleVO.staticQuery); + + + System.out.println("=========================================="); + System.out.println("Test - static field getter/setter ( static 필드에 직접 값 설정 )"); + System.out.println("=========================================="); + ExampleVO.staticQuery = "delete from dual"; + System.out.println("vo1.staticQuery = " + vo1.getStaticQuery()); + System.out.println("vo2.staticQuery = " + vo2.getStaticQuery()); + System.out.println("ExampleVO.staticQuery = " + ExampleVO.staticQuery); + + + System.out.println("=========================================="); + System.out.println("Test - private field getter/setter "); + System.out.println("=========================================="); + vo1.setQuery("select count(1) from dual"); + System.out.println("vo1.query = " + vo1.getQuery()); + System.out.println("vo2.query = " + vo2.getQuery()); + + } +} diff --git a/src/test/java/cokr/xit/ntri/ExampleVO.java b/src/test/java/cokr/xit/ntri/ExampleVO.java new file mode 100644 index 0000000..8d2eafd --- /dev/null +++ b/src/test/java/cokr/xit/ntri/ExampleVO.java @@ -0,0 +1,23 @@ +package cokr.xit.ntri; + +public class ExampleVO { + static String staticQuery; + + private String query; + + public void setStaticQuery(String query) { + ExampleVO.staticQuery = query; + } + + public String getStaticQuery() { + return staticQuery; + } + + public void setQuery(String query) { + this.query = query; + } + + public String getQuery() { + return this.query; + } +} diff --git a/src/test/java/cokr/xit/ntri/NtriApplicationTests.java b/src/test/java/cokr/xit/ntri/NtriApplicationTests.java new file mode 100644 index 0000000..9f0aa65 --- /dev/null +++ b/src/test/java/cokr/xit/ntri/NtriApplicationTests.java @@ -0,0 +1,13 @@ +package cokr.xit.ntri; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class NtriApplicationTests { + + @Test + void contextLoads() { + } + +}