[Spring Boot][Total-Back-Office Project] AOP, Annotation์„ ์ด์šฉํ•œ API ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ feat.MyBatis & Test Code(JUnit 5)

2023. 7. 16. 23:32ใ†Back-End ์ž‘์—…์‹ค/Spring Framework

728x90
๋ฐ˜์‘ํ˜•

 

 

 

 

 

 

์Šคํ”„๋ง ๋ถ€ํŠธ 3 ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ๋˜๊ธฐ : ์ž๋ฐ” ํŽธ

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

 




๐Ÿ—‚ ๋ชฉ์ฐจ

๐Ÿง‘‍๐Ÿ’ป ์ฝ”๋”ฉ

โœ…  [Spring Boot][Total-Back-Office Project] AOP, Annotation์„ ์ด์šฉํ•œ API ๋™์ž‘ ์‹œ๊ฐ„ ์ธก์ •
โœ… [Spring Boot][Total-Back-Office Project] AOP, Annotation์„ ์ด์šฉํ•œ API ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ feat.MyBatis & Test Code(JUnit 5) (https://junyharang.tistory.com/457
)

โœ… [Spring Boot][Total-Back-Office Project] Log Back์„ ์ด์šฉํ•œ Discord์— Exception ์ •๋ณด ๋ณด๋‚ด๊ธฐ ๋ฐ Data Base  ์ €์žฅ feat.MyBatis & Test Code(JUnit 5) - โ‘  Log Back ์„ค์ •
โœ… [Spring Boot][Total-Back-Office Project] Log Back์„ ์ด์šฉํ•œ Discord์— Exception ์ •๋ณด ๋ณด๋‚ด๊ธฐ ๋ฐ Data Base ์ €์žฅ feat.MyBatis & Test Code(JUnit 5) - โ‘ก ๋””์Šค์ฝ”๋“œ๋กœ ๋กœ๊ทธ ์ •๋ณด ๋ฐœ์†ก
โœ… [Spring Boot][Total-Back-Office Project] Log Back์„ ์ด์šฉํ•œ Discord์— Exception ์ •๋ณด ๋ณด๋‚ด๊ธฐ ๋ฐ Data Base ์ €์žฅ feat.MyBatis & Test Code(JUnit 5) - โ‘ข ๋กœ๊ทธ ๋ฐ ์š”์ฒญ ์ด์šฉ์ž, ์š”์ฒญ ์ •๋ณด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅ

 

๐Ÿšš ๋ฐฐํฌ

โš ๏ธ ์•„๋ž˜ ๋ชฉ์ฐจ ์ค‘ ๋ช‡๋ช‡๊ฐœ์˜ ๋งํฌ๊ฐ€ ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š” ๋ฌธ์ œ๋กœ ๊ธ€ ๋งจ ํ•˜๋‹จ์— ๋‹ค์Œ ๊ธ€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

โœ… [CI/CD] Jenkins์™€ Gitea ์—ฐ๋™
โœ… [CI/CD] Jenkins Trigger ์ •๋ณด Discord๋กœ ๋ณด๋‚ด๊ธฐ
โœ… [CI/CD] ์ •์  ์ฝ”๋“œ ๋ถ„์„ ํˆด SonarQube์™€ Jenkins ์—ฐ๋™
โœ… [CI/CD] SonarQube๋ฅผ ํ†ตํ•ด Code Convention ์ ์šฉ
โœ… [DevOps] JAVA Gradle JaCoCo (Code coverage) ์„ค์ •ํ•˜๊ธฐ 
โœ… [DevOps] JAVA Gradle JaCoCo (Code coverage) ์„ค์ •ํ•˜๊ธฐ (์ถ”๊ฐ€)(https://junyharang.tistory.com/392)

โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘  Application Linuxt(Ubuntu)์— SSH๋ฅผ ์ด์šฉํ•œ ํŒŒ์ผ ์ „์†ก
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ก Create Docker Image And BackUp
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ข Application Server Docker Job (โ‘  Application ๋„์ปค ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ)
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ข Application Server Docker Job (โ‘ก Application Docker Run)(https://junyharang.tistory.com/406)
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ข Application Server Docker Job (โ‘ข Application Docker Health Check)
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘  NGINX ๊ฐ ์ข… ์„ค์ •) 
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘ก NGINX Docker ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ) 
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘ข NGINX Docker Run & Health Check)
โœ… [CI/CD] Jenkins + Docker๋ฅผ ์ด์šฉํ•œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ - โ‘ฃ NGINX Server Docker Job (โ‘ข NGINX ์žฌ ์„ค์ •)

 

 

 

๐Ÿ’พ Git Hub Repository : https://github.com/junyharang-personal-project/junyss-total-back-office

 

GitHub - junyharang-personal-project/junyss-total-back-office: [Back-Office] ๋””์Šค์ฝ”๋“œ ๋ด‡๊ณผ Logback, AOP ๋“ฑ์„ ์ด์šฉํ•˜

[Back-Office] ๋””์Šค์ฝ”๋“œ ๋ด‡๊ณผ Logback, AOP ๋“ฑ์„ ์ด์šฉํ•˜์—ฌ ์ด์šฉ์ž ์ ‘์† ์ •๋ณด, Exception ์ •๋ณด ๋“ฑ์„ ๋””์Šค์ฝ”๋“œ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋น„์Šค - GitHub - junyharang-personal-project/junyss-total-back-office: [Back-Office] ๋””์Šค์ฝ”๋“œ

github.com

 

 

 

 

 

๐Ÿš€ AOP, Annotation์„ ์ด์šฉํ•œ API ์ ‘์† ์ด์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

    ๐Ÿ”ฝ ๊ฐœ์š”

        ๐Ÿ“ฆ ์†Œ๊ฐœ

์ตœ๊ทผ ์ฃผ๋‹ˆ๊ฐ€ ์ง„ํ–‰ํ•œ ํ”„๋กœ์ ํŠธ์—์„œ AOP์™€ Annotation์„ ๋งŒ๋“ค์–ด API ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด ๋ฐ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ๋ณด์•˜์–ด์š”.

์ด์— ๋Œ€ํ•ด ์ •๋ฆฌํ•˜๊ณ , ๊ณต์œ ํ•ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

 

AOP๋ž€?

AOP์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ์ด ๊ณณ๊ณผ ์ด ๊ณณ์— ์ •๋ฆฌํ•ด ๋‘์—ˆ์–ด์š”.

 

[Spring] Spring AOP; ์Šคํ”„๋ง AOP ๊ฐœ๋… ์ •๋ฆฌ

๐Ÿš€ ์Šคํ”„๋ง AOP ๊ฐœ๋… ์ •๋ฆฌ ๐Ÿ”ฝ ์ด๋ก  ๐Ÿ“ฆ AOP๋ž€? AOP๋Š” Aspect Oriented Programming์˜ ์•ฝ์ž๋กœ ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ณ  ์žˆ์–ด์š”. ์ด๊ฒƒ์€ ์–ด๋–ค ๋กœ์ง ๊ธฐ์ค€ ํ•ต์‹ฌ์ ์ธ ๊ด€์ ๊ณผ ๋ถ€๊ฐ€์ ์ธ ๊ด€์ ์„ ๋‚˜๋ˆ„๊ณ ,

junyharang.tistory.com

๋ฐ˜์‘ํ˜•
 

[Spring Boot] AOP

์•ˆ๋…•ํ•˜์„ธ์š”? ์ฃผ๋‹ˆํ•˜๋ž‘ ์ž…๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ AOP์— ๋Œ€ํ•ด ๊ณต๋ถ€ ํ•ด ๋ณด๋„๋ก ํ•  ๊ฒƒ์ด์—์š”. ๋ฐ”๋กœ ์‹œ์ž‘ ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค! ์ฝ”๋“œ์— ๊ด€๋ จํ•œ ๋‚ด์šฉ์€ ์ฃผ๋‹ˆํ•˜๋ž‘์˜ Github์—์„œ ํ™•์ธ ํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๐Ÿ“‹ ๋ชฉ์ฐจ 01.[Spring Boo

junyharang.tistory.com

 

Annotation์ด๋ž€?

์–ด๋…ธํ…Œ์ด์…˜์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ์ด ๊ณณ์— ์ •๋ฆฌํ•ด ๋‘์—ˆ์–ด์š”.

 

[Java] Annotation (์–ด๋…ธํ…Œ์ด์…˜) ์ด๋ž€?

์Šคํ”„๋ง ๋ถ€ํŠธ 3 ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ๋˜๊ธฐ : ์ž๋ฐ” ํŽธ COUPANG www.coupang.com "์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค." ๐Ÿš€ Annotaion (์–ด๋…ธํ…Œ์ด์…˜) ์ด๋ž€? ๐Ÿ”ฝ ๊ฐœ

junyharang.tistory.com

 

 

 

        ๐Ÿ“ฆ Data Base ๊ตฌ์กฐ

Data Base ๊ตฌ์กฐ

 

 

 

 

 

 

    ๐Ÿ”ฝ  ์†Œ์Šค ์ฝ”๋“œ ๋ถ„์„

        ๐Ÿ“ฆ UserAccessInfoAspect.java

Code๋ฅผ ๋ถ„์„ํ•˜๊ธฐ ์ „ AOP ๊ด€๋ จํ•˜์—ฌ ์ง€๋‚œ ๊ธ€๊ณผ ๊ณตํ†ต๋œ ์‚ฌํ•ญ์€ ์ด ๊ณณ์—์„œ ๋ณด๋‹ค ์ž์„ธํžˆ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์–ด์š”.

 

[Spring Boot][Total-Back-Office Project] AOP, Annotation์„ ์ด์šฉํ•œ API ๋™์ž‘ ์‹œ๊ฐ„ ์ธก์ •

์Šคํ”„๋ง ๋ถ€ํŠธ 3 ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ๋˜๊ธฐ : ์ž๋ฐ” ํŽธ COUPANG www.coupang.com "์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค." ๐Ÿ—‚ ๋ชฉ์ฐจ โœ… [Spring Boot][Total-Back-Office Pr

junyharang.tistory.com

 

UserAccessInfoAspect 31 ~ 51๋ฒˆ์งธ ์ค„


์ตœ์ดˆ 43๋ฒˆ์งธ ์ค„์— ์š”์ฒญ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด ์ฃผ์—ˆ์–ด์š”.
ํ•ด๋‹น ์ฝ”๋“œ๋Š” Spring Framework์˜ WebUtils Class๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HttpServletRequest ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ถ€๋ถ„์ด์—์š”.

HttpServletRequest๋Š” Java Servlet API์˜ ์ผ๋ถ€๋กœ Web Application์—์„œ Client์˜ HTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์บก์Šํ™”ํ•˜๋Š” Interface๋ž๋‹ˆ๋‹ค.

WebUtils.getNativeRequest()๋Š” ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ฉ”์†Œ๋“œ๋กœ HttpServletRequest ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์–ด์š”.

ํ•ด๋‹น ๋ฉ”์†Œ๋“œ์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ HttpServletRequest.class๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋ ค๋Š” ๊ฐ์ฒด Type์„ ๋ช…์‹œํ•˜๊ณ  ์žˆ์–ด์š”.

์ฃผ๋‹ˆ๊ฐ€ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š” ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ HttpServletRequest์˜ wrapper์ธ Request ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ์ง์ ‘ HttpServletRequest ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•จ์ด์—์š”.

์˜ˆ๋ฅผ ๋“ค์–ด HttpServletRequest์˜ ๊ธฐ๋Šฅ๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•œ ์ƒํ™ฉ์ด๊ฑฐ๋‚˜, ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํŠน์ • ๋ถ€๋ถ„์—์„œ HttpServletRequest๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ๊ทธ ์˜ˆ๊ฐ€ ๋  ๊ฑฐ ๊ฐ™์•„์š”.

์ฆ‰, ์ด ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์š”์ฒญ ์ด์šฉ์ž์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„์ด์—์š”.


45๋ฒˆ์งธ ์ค„๊ณผ 46๋ฒˆ์งธ ์ค„์—๋Š” ์ด์šฉ์ž์˜ ์ ‘์† ์ผ์‹œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ ๋ถ€๋ถ„์ด์—์š”.
45๋ฒˆ์งธ ์ค„์— yyyy-mm-dd HH(24์‹œ๊ฐ„ ํ‘œ๊ธฐ):mm:ss๋กœ ์ ‘์† ์ผ์‹œ์— ๋Œ€ํ•œ Format์„ ์ง€์ •ํ•ด ์ฃผ๊ณ , 46๋ฒˆ์งธ ์ค„์—์„œ Date ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด System.currentTimeMillis() ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š”๋ฐ ์ด๋Š” 1970๋…„ 1์›” 1์ผ 00:00:00 GMT(๊ทธ๋ฆฌ๋‹ˆ์น˜ ํ‘œ์ค€์‹œ)๋กœ ๋ถ€ํ„ฐ ํ˜„์žฌ๊นŒ์ง€ ๊ฒฝ๊ณผํ•œ ์‹œ๊ฐ„์„ ms(๋ฐ€๋ฆฌ์ดˆ) ๋‹จ์œ„๋กœ ์ ‘์† ์ผ์‹œ๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•จ์ด๊ณ , Date Class์˜ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ๋‚ ์งœ์™€ ์‹œ๊ฐ„์„ ๋‚˜ํƒ€๋‚ด๋Š” Date ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ด ๋•Œ ์ „๋‹ฌ๋œ ๊ฐ’์€ Date ๊ฐ์ฒด๊ฐ€ ๋‚˜ํƒ€๋‚ด๋Š” ์‹œ๊ฐ„์„ ms ๋‹จ์œ„๋กœ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

๊ฒฐ๊ตญ ํ˜„์žฌ ์‹œ๊ฐ„์„ ๋ฐ€๋ฆฌ์ดˆ ๋‹จ์œ„๋กœ ๋ฐ›์•„์™€์„œ ๊ทธ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์‹œ๊ฐ„์„ ๋‚˜ํƒ€๋‚ด๋Š” Date ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ ๊ฒƒ์ด์—์š”.

์ฐธ๊ณ ๋กœ Java 8๋ถ€ํ„ฐ๋Š” java.time.LocalDateTime ํ˜น์€ java.time.ZonedDateTime ๋“ฑ์ด ์ œ๊ณต๋˜๋ฉฐ, ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ผ ์ˆ˜๋„ ์žˆ์–ด์š”.

์™œ๋ƒํ•˜๋ฉด Date Class๋Š” ์ด์ „ ๋ฒ„์ „์˜ ๋‚ ์งœ์™€ ์‹œ๊ฐ„ API์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•˜๋ฉด java.time Package๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ ์งœ์™€ ์‹œ๊ฐ„์„ ๋‹ค๋ฃจ๋Š”๊ฒŒ ์ข‹๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

๊ทธ๋Ÿฐ ๋’ค split()์„ ํ†ตํ•ด ๊ณต๋ฐฑ์„ ๊ธฐ์ค€์œผ๋กœ ๋‘ ๊ฐœ์˜ ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ง€๊ฒŒ ํ•˜๊ณ , ์ฒซ๋ฒˆ์งธ ๋ฐฐ์—ด์—๋Š” ๋‚ ์งœ๊ฐ’์ด ๋‘๋ฒˆ์งธ ๋ฐฐ์—ด์—๋Š” ์‹œ๊ฐ„๊ฐ’์ด ๋‹ด๊ธธ ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

 

UserAccessInfoAspect 54 ~ 83๋ฒˆ์งธ ์ค„


์ด์ œ ์œ„์—์„œ ๊ฐ€์ ธ์˜จ ์ด์šฉ์ž ์ ‘์† ์ •๋ณด์™€ ์ ‘์† ์ผ์‹œ๋ฅผ Data Base์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ Logic์„ ๊ตฌํ˜„ํ•ด ์ฃผ์—ˆ์–ด์š”.

์ตœ์ดˆ 54 ~ 60๋ฒˆ์งธ ์ค„๊นŒ์ง€ ์ ‘์† ์ด์šฉ์ž ์ •๋ณด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ save()์— ์ด์šฉ์ž ์ ‘์† ์ •๋ณด๋ฅผ ๋‹ด์€ ์š”์ฒญ DTO๋ฅผ Builder Pattern์œผ๋กœ ์ „๋‹ฌํ•ด ์ค๋‹ˆ๋‹ค.


์ด ๋•Œ, 55๋ฒˆ์งธ ์ค„์— ํ˜„์žฌ ๊ตฌ๋™์ค‘์ธ ์„œ๋ฒ„ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ๊ฒŒ ๋˜๋Š”๋ฐ, ํ•ด๋‹น ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์•„์š”.


Environment 60 ~ 84๋ฒˆ์งธ ์ค„


ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋Š” Exception์ด ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜, ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•  ๋•Œ, ๊ตฌ๋™ Application์˜ ์„œ๋ฒ„ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ์—์š”.

66๋ฒˆ์งธ ์ค„์— SpringApplication ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š”๋ฐ, ํ•ด๋‹น ๊ฐ์ฒด๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํด๋ž˜์Šค์—์š”. ์ด ํด๋ž˜์Šค์— SystemInfo.class๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š”๋ฐ, ์ด๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฉ”์ธ ํด๋ž˜์Šค๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ต๋‹ˆ๋‹ค.

setWebApplicationType(WebApplicationType.None)์€ ์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์•„๋‹Œ ์ผ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •ํ•˜๋Š” ๋ถ€๋ถ„์ด์—์š”. ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์›น ์„œ๋ฒ„์™€ ์—ฐ๋™ํ•˜๋Š” ๋“ฑ์˜ ์ถ”๊ฐ€ ์„ค์ •์ด ํ•„์š”ํ•˜์ง€๋งŒ, ์ด ์„ค์ •์„ ํ†ตํ•ด ์›น ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ์ผ๋ฐ˜์ ์ธ ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

ManagementFactory.getRuntimeMXBean()์—์„œ ManagementFactory ํด๋ž˜์Šค๋Š” ์ž๋ฐ” Management Extensions(JMX) API๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ, getRuntimeMXBean()์€ JVM์˜ Runtime System ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” RuntimeMXBean ์ธํ„ฐํŽ˜์ด์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋œ๋‹ต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค ์„œ๋ฒ„ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.

โˆ™ runtimeMXBean.getVmName(): JVM(์ž๋ฐ” ๊ฐ€์ƒ ๋จธ์‹ ) ์ด๋ฆ„๊ณผ ๋ฒ„์ „ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ.

โˆ™ System.getProperty(): System Property๋ฅผ ์ด์šฉํ•˜์—ฌ ์šด์˜์ฒด์ œ(OS) ์ด๋ฆ„, ๋ฒ„์ „, ์•„ํ‚คํ…์ฒ˜ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ.
โˆ™ InetAddress.getLocalHost().getHostAddress(): InetAddress ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ
   Local Host IP ์ฃผ์†Œ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ.
   (์ด ๋•Œ, UnknownHostException์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— 80๋ฒˆ์งธ ์ค„์— catch ์ ˆ์„ ํ†ตํ•ด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ)

โˆ™ ServerInfo.builder()...build(): ServerInfo ํด๋ž˜์Šค์˜ ๋นŒ๋” ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„ ์ •๋ณด๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ ๋ฐ›๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ.

80๋ฒˆ์งธ ์ค„์— ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„์€ IP ์ฃผ์†Œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” UnknownHostException์„ ์บ์น˜ํ•˜์—ฌ ServerInfoException์ด๋ผ๋Š” ์ฃผ๋‹ˆ๊ฐ€ ๋งŒ๋“  ์ปค์Šคํ…€ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋„๋ก ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”. ํ•ด๋‹น ์˜ˆ์™ธ๋Š” ์ด ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ณณ์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

์ด๋ ‡๊ฒŒ ํ•ด์„œ ์Šคํ”„๋ง ๋ถ€ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„์˜ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ , ์ด๋ฅผ ServerInfo ๊ฐ์ฒด๋กœ ๋นŒ๋“œํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ด ์ค€ ๊ฒƒ์ด์—์š”.

์„œ๋ฒ„์˜ ์šด์˜์ฒด์ œ, JVM ์ •๋ณด, ์„œ๋ฒ„์˜ IP ์ฃผ์†Œ ๋“ฑ์„ ์ˆ˜์ง‘ํ•˜๊ณ , ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์•„๋‹ˆ๋”๋ผ๋„ ์ผ๋ฐ˜์ ์ธ ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.



UserRequestTotalInfoSaveRequestDto


UserAccessInfoAspect 54๋ฒˆ์งธ ์ค„์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ํ•ด๋‹น DTO๋ฅผ ๋นŒ๋” ํŒจ๋˜์œผ๋กœ ๊ฐ’์„ ๋„ฃ์–ด ์ „๋‹ฌํ•œ๋‹ค๊ณ  ํ–ˆ์–ด์š”.

ํ•ด๋‹น DTO๋Š” ์œ„์™€ ๊ฐ™์ด ํ•„์š”ํ•œ ๊ฐ์ฒด๋“ค์„ ๋‹ด๊ฒŒ ๋˜์–ด ์žˆ๋Š”๋ฐ, ์„œ๋ฒ„ ์ •๋ณด, ์ด์šฉ์ž ์š”์ฒญ ์ผ์‹œ DTO, ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ์š”์ฒญ DTO (WAS ์ˆœ์„œ ๋ฒˆํ˜ธ, ์ ‘์† ์ผ์‹œ ์ˆœ์„œ ๋ฒˆํ˜ธ, ์ด์šฉ์ž IP, ์ด์šฉ์ž ์ ‘์† ์œ„์น˜ ์ •๋ณด, ์ด์šฉ์ž ํ™˜๊ฒฝ ์ •๋ณด), ์š”์ฒญ ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด DTO (WAS ์ˆœ์„œ ๋ฒˆํ˜ธ, ์ ‘์† ์ผ์‹œ ์ˆœ์„œ ๋ฒˆํ˜ธ, ์ด์šฉ์ž ์ˆœ์„œ ๋ฒˆํ˜ธ, ์š”์ฒญ ํ—ค๋” ์ •๋ณด, ์ฟ ํ‚ค ์ •๋ณด, ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์ •๋ณด, ์š”์ฒญ ๋ฐ”๋”” ์ •๋ณด)๋ฅผ ๋ฐ›๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.


ServerInfo



DataCreatedDateTimeRequestDto



ConnectedUserInfoSaveRequestDto (์ ‘์† ์ด์šฉ์ž ์ •๋ณด ๋‹ด๊ธฐ ์œ„ํ•œ DTO)

 

 

ConnectedUserRequestInfoSaveRequestDto (์ด์šฉ์ž ์ ‘์† ์š”์ฒญ ์ •๋ณด ๋‹ด๊ธฐ ์œ„ํ•œ DTO)

 

 

 

UserAccessInfoAspect 54 ~ 83๋ฒˆ์งธ ์ค„


๋‹ค์‹œ ์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด ๋ณด๋ฉด 56๋ฒˆ์žฌ ์ค„์— ์ด์šฉ์ž ์ ‘์† ์ผ์‹œ ์ •๋ณด๋ฅผ ๋‹ด๊ธฐ ์œ„ํ•ด DataCreatedDateTimeRequestDTO๋ฅผ UserRequestTotalInfoSaveRequestDto ๊ฐ์ฒด์— ๋นŒ๋” ํŒจํ„ด์œผ๋กœ ์ „๋‹ฌํ•˜๋Š”๋ฐ, ์ด ๋•Œ, DataCreatedDateTimeRequestDto ๊ฐ์ฒด ์—ญ์‹œ ๋นŒ๋” ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ 46๋ฒˆ์งธ splitNowDateTime ๋ฐฐ์—ด์— ๋‹ด๊ธด ๋‚ ์งœ๊ฐ’๊ณผ ์‹œ๊ฐ„๊ฐ’์„ ๊ฐ๊ฐ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์–ด์š”.

62๋ฒˆ์งธ ๋ถ€ํ„ฐ 69๋ฒˆ์งธ ์ค„๊นŒ์ง€๋Š” ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋กœ์ง์ธ๋ฐ, ์ด ๋•Œ, CryptoUtil ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด์šฉ์ž ์ฃผ์š” ์ •๋ณด๋ฅผ ์•”ํ˜ธํ™” ํ•˜๋„๋ก ํ•˜์˜€์–ด์š”.

CryptoUtil 229 ~ 241๋ฒˆ์งธ ์ค„


ํ•ด๋‹น ์ฝ”๋“œ๋Š” ์ฃผ๋‹ˆ๊ฐ€ ๋งŒ๋“  Data-Aes-Secret Library๋ฅผ Jitpack์„ ํ†ตํ•ด ์˜คํ”ˆ ์†Œ์Šค๋กœ ๊ณต๊ฐœํ•œ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์˜€๊ณ , ์ด๋ฅผ ํ†ตํ•ด AES 256์œผ๋กœ ์•”ํ˜ธํ™” ํ•˜์—ฌ ์ฃผ์š” ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ค€ ๋ถ€๋ถ„์ด์—์š”.

ํ•ด๋‹น ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ๋Š” ์ด ๊ณณ์— ์ž์„ธํžˆ ์ค€๋น„ ํ•ด ๋‘์—ˆ์–ด์š”.

 

GitHub - JunyHarang-Open-Source-project/Data-Aes-Secret: ์ฃผ์š” Data AES ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ†ตํ•œ ์•” / ๋ณตํ˜ธํ™” Library

์ฃผ์š” Data AES ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ†ตํ•œ ์•” / ๋ณตํ˜ธํ™” Library. Contribute to JunyHarang-Open-Source-project/Data-Aes-Secret development by creating an account on GitHub.

github.com

728x90

์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด ๋ณด๋ฉด userInfoEncrypt()๋Š” ConnectedUserInfoSaveRequestDto ๊ฐ์ฒด๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ ๋ฐ›๊ฒŒ ๋˜์š”.

๊ทธ๋ฆฌ๊ณ , ๊ฐ๊ฐ์˜ ์•”ํ˜ธํ™”๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋Š” ๋ถ€๋ถ„ (์ด์šฉ์ž IP, ์ด์šฉ์ž ์ ‘์† ์œ„์น˜ ์ •๋ณด, ์ด์šฉ์ž ์ ‘์† ํ™˜๊ฒฝ)์„ AES 256์œผ๋กœ ์•”ํ˜ธํ™” ํ•˜๋„๋ก ํ•ด ์ฃผ์—ˆ๊ณ , DataSecret.base64Encoder()์— ์•”ํ˜ธํ™”์— ํ•„์š”ํ•œ cipherKey๊ฐ’์„ ์ „๋‹ฌํ•˜์—ฌ ์•”ํ˜ธํ™” ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ค€ ๋’ค Setter๋ฅผ ํ†ตํ•ด ๋‹ค์‹œ ํ•ด๋‹น DTO์— ๊ฐ’์„ ์ €์žฅํ•˜๊ณ , ์ด ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜์˜€์–ด์š”.

๊ทธ๋ ‡๊ฒŒ ์•”ํ˜ธํ™”๊ฐ€ ๋œ ์ด์šฉ์ž ์ •๋ณด๋ฅผ UserRequestTotalInfoSaveRequestDto์— ๋‹ด๊ธธ ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ์—ˆ๋‹ต๋‹ˆ๋‹ค.


UserAccessInfoAspect 54 ~ 83๋ฒˆ์งธ ์ค„


๋งˆ์ง€๋ง‰์œผ๋กœ 70 ~ 78๋ฒˆ์งธ ์ค„์— ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋‹ด๊ธฐ ์œ„ํ•œ DTO๋ฅผ ๋นŒ๋” ํŒจํ„ด์œผ๋กœ ์ €์žฅํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด ๋•Œ๋„ ์—ญ์‹œ ์•”ํ˜ธํ™”๋ฅผ ํ•ด์„œ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

CryptoUtil 282 ~ 311๋ฒˆ์งธ ์ค„


userRequestInfoEncryp()๋Š” ConnectedUserRequestInfoSaveRequestDto๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋ฐ›๊ฒŒ ๋˜๋Š”๋ฐ, ์ตœ์ดˆ ํ•ด๋‹น ๊ฐ์ฒด Null Check๋ฅผ ํ•ด์ฃผ๊ณ , Null ์ด๋ผ๋ฉด ์ฃผ๋‹ˆ๊ฐ€ ๋งŒ๋“  CryptoException์ด ํ„ฐ์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€์–ด์š”.

Null์ด ์•„๋‹ˆ๋ผ๋ฉด ์š”์ฒญ ํ—ค๋”, ์ฟ ํ‚ค ์ •๋ณด, ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์ •๋ณด, ์š”์ฒญ ๋ฐ”๋”” ์ •๋ณด ์•”ํ˜ธํ™” ํ•˜๋„๋ก ํ•˜๊ณ , ์•”ํ˜ธํ™” ๋œ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด DTO ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ด ์ฃผ์—ˆ๋‹ต๋‹ˆ๋‹ค.

 

 

 

 

        ๐Ÿ“ฆ UserAccessInfoCheck.java

์ด์ œ ํ•ด๋‹น AOP๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ณณ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์–ด๋…ธํ…Œ์ด์…˜์„ ๋งŒ๋“ค์–ด ์ฃผ์–ด์•ผ ํ•ด์š”.

UserAccessInfoCheck.java


์ฃผ๋‹ˆ๋Š” ์œ„์™€ ๊ฐ™์ด Method์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์„ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ๊ณ , ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ Runtime์—์„œ ์ง€์†์ ์œผ๋กœ ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด ์ฃผ์—ˆ์–ด์š”.







        ๐Ÿ“ฆ ConnectedUserInfoService.java

ConnectedUserInfoService Interface save()




ConnectedUserInfoServiceImpl 55 ~ 94๋ฒˆ์งธ ์ค„



์ด์ œ ์ด ๊ณณ์—์„œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์ด์šฉ์ž ์ ‘์† ์ •๋ณด๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์—ฌ์ •์ด ์‹œ์ž‘๋˜์š”.

save()๋Š” UserRequestTotalInfoSaveRequestDto ๊ฐ์ฒด๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋ฐ›๊ฒŒ ๋˜๊ณ , 72๋ฒˆ์งธ ์ค„์— ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ Null์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ , Null์ด๋ฉด ์ฃผ๋‹ˆ๊ฐ€ ๋งŒ๋“  ConnectedUserException์ด ํ„ฐ์ง€๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•  ๋•Œ, ์œ„์—์„œ ์„œ๋ฒ„ ์ •๋ณด, ์ ‘์† ์ผ์‹œ, ์ ‘์† ์ด์šฉ์ž ์ •๋ณด, ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด๋ฅผ ๊ฐ๊ฐ ๋‚˜๋ˆ„์–ด์„œ ๊ฐ์ฒด์— ์ €์žฅํ–ˆ๋Š”๋ฐ, ์ด์œ ๋Š” ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ ๋ถ„๋ฆฌํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.



Data Base ๊ตฌ์กฐ

 

์œ„์™€ ๊ฐ™์ด ์„œ๋ฒ„ ์ •๋ณด, ์ ‘์† ์ผ์‹œ, ์ ‘์† ์ด์šฉ์ž ์ •๋ณด, ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด๋ฅผ ๊ฐ๊ฐ ํ…Œ์ด๋ธ”์„ ๋ถ„๋ฆฌํ•ด์„œ ๋ฐ›๊ฒŒ ํ•ด์ฃผ์—ˆ๊ณ ,
์ด ์ด์œ ๋กœ 78 ~ 86๋ฒˆ์งธ ์ค„๊นŒ์ง€ ๊ฐ๊ฐ์˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ  ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.


ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋“ค์ด ๋ชจ๋‘ ์ž‘๋™๋˜์–ด ๊ฐ๊ฐ์˜ ์ •๋ณด๊ฐ€ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅ๋˜๋ฉด PK ๊ฐ’์„ ๋ฐ˜ํ™˜๋ฐ›๊ฒŒ ๋˜๊ณ , ํ•ด๋‹น PK ๊ฐ’์„ resultMap์— ๊ฐ๊ฐ ๋‹ด์•„ ๋ฐ˜ํ™˜ ์‹œ์ผœ ์ค€๋‹ต๋‹ˆ๋‹ค.

 

 

 

processServerInfosaver()

์ตœ์ดˆ ์„œ๋ฒ„ ์ •๋ณด ์ €์žฅ์„ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ๊ฒŒ์š”.

ConnectedUserInfoServiceImpl 170 ~ 197๋ฒˆ์งธ ์ค„


ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋Š” ์„œ๋ฒ„ ์ •๋ณด๋ฅผ ๋‹ด์€ ServerInfo ๊ฐ์ฒด๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋ฐ›๊ณ  ์žˆ์–ด์š”.

์ตœ์ดˆ ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ Null์ธ์ง€ ํ™•์ธํ•˜๊ณ , Null์ด๋ผ๋ฉด ์ฃผ๋‹ˆ๊ฐ€ ๋งŒ๋“  ServerInfoException์ด ํ„ฐ์ง€๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

Null์ด ์•„๋‹ˆ๋ผ๋ฉด ServerInfoDAO.serverID()๋ฅผ ํ†ตํ•ด ServerInfo ๊ฐ์ฒด์— ๋‹ด๊ธด ์„œ๋ฒ„ IP ์ฃผ์†Œ๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ ๋™์ผ ์„œ๋ฒ„ IP๊ฐ€ ์žˆ๋Š”์ง€๋ฅผ ์ฐพ๊ณ , ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ์ •๋ณด์˜ PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜์˜€์–ด์š”.


ServerInfoDaoImpl.java findByServerID()



ServerManagementMapper.java


์œ„์™€ ๊ฐ™์ด MyBatis๋ฅผ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„ IP์ฃผ์†Œ๋ฅผ ํ†ตํ•ด ๋‚ด๋ถ€ ์„œ๋ฒ„ PK ๊ฐ’์„ ๋ฐ˜ํ™˜ ๋ฐ›๋„๋ก ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.

 

ConnectedUserInfoServiceImpl 170 ~ 197๋ฒˆ์งธ ์ค„


๋‹ค์‹œ ์œ„ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด ๋ณด๋ฉด 185๋ฒˆ์งธ ์ค„์— ํ•ด๋‹น ID ๊ฐ’์ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๊ณ , ์—†๋‹ค๋ฉด ServerInfo ๊ฐ์ฒด์— ์ €์žฅ๋œ ์„œ๋ฒ„ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก serverInfoDAO.save()์— ServerInfoVo.toVo()๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š”๋ฐ, toVo()์—๋Š” ๋‹ค์‹œ ServerInfoSaveRequestDto์˜ ๋นŒ๋” ํŒจํ„ด์„ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„ ์ด๋ฆ„, JVM ์ •๋ณด, ์„œ๋ฒ„ OS ์ •๋ณด, IP ์ •๋ณด, ๊ตฌ๋™ ํ™˜๊ฒฝ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜์—ฌ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์–ด์š”.

์•„๋ž˜ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์ €์žฅ์ด ๋๋‚˜๋ฉด ๋ฐ˜ํ™˜ ๋ฐ›์€ PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋˜๊ณ , ๋งŒ์•ฝ 185๋ฒˆ์งธ ์ค„์— ์ด๋ฏธ ํ•ด๋‹น ์ •๋ณด๊ฐ€ ์žˆ์–ด ID๊ฐ€ ์žˆ์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด ํ•ด๋‹น ID ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.


ServerInfoSaveRequestDto



ServerInfoVo



์ด์ œ DAO์™€ Mapper๋Š” ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ–ˆ๋Š”์ง€ ๋ถ„์„ํ•ด ๋ณผ๊ฒŒ์š”.


ServerInfoDaoImpl 1 ~ 31๋ฒˆ์งธ ์ค„



ServerManagementMapper 1 ~ 23๋ฒˆ์งธ ์ค„



ServerManagementMapper.xml


์œ„์™€ ๊ฐ™์ด Mapper.xml์„ ์ด์šฉํ•˜์—ฌ SQL๋ฌธ์„ ์ž‘์„ฑํ•ด ์ฃผ์—ˆ๊ณ , ServerInfoVo ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌ ๋ฐ›์•„ ๊ฐ๊ฐ์˜ ๊ฐ’๋“ค์„ ์ €์žฅ ์‹œ์ผœ ์ฃผ์—ˆ๊ณ , userGenerateKeys์™€ keyProperty๋ฅผ ํ†ตํ•ด ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ PK ๊ฐ’ ๋ฐ˜ํ™˜๋˜๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

 

 

 

processOccurrenceInfoDateTimeSave()

์ด๋ฒˆ์—๋Š” ์ด์šฉ์ž ์š”์ฒญ ์ผ์‹œ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฉ”์†Œ๋“œ์—์š”.

ConnectedUserInfoServiceImpl 199 ~ 229 ๋ฒˆ์งธ ์ค„


์ด ๋ฉ”์†Œ๋“œ๋„ ์œ„์™€ ๊ฐ™์ด ๋จผ์ € ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๊ฐ์ฒด์— ๋Œ€ํ•œ Null Check ์ง„ํ–‰์„ ํ•œ ๋’ค Null์ด ์•„๋‹ ๊ฒฝ์šฐ occurrenceDataDateTimeManagementDAO.findByOccurrenceInfoDateTime()์—๊ฒŒ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ DataCreatedDateTimeRequestDto์— ๋‹ด๊ธด ์ด์šฉ์ž ์š”์ฒญ ์ผ์‹œ๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ์–ด ํ•ด๋‹น ์ •๋ณด๊ฐ€ ์ €์žฅ ๋˜์–ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•ด ์ฃผ์—ˆ์–ด์š”.


OccurrenceDataDateTimeManagementDaoImpl findByOccurrenceInfoDateTime()



OccurrenceDataDateTimeManagementMapper findByOccurrenceInfoDateTime()


์œ„์™€ ๊ฐ™์ด SQL ๋ฌธ์„ ์ž‘์„ฑํ•ด ์ฃผ์—ˆ๋Š”๋ฐ, SQL Select ๋ฌธ์„ ํ†ตํ•ด ์ตœ์ดˆ max()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋“ค ์ค‘์—์„œ data_created_date_time_id ์—ด (PK)์˜ ์ตœ๋Œ€๊ฐ’์„ ์ฐพ๋„๋ก ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

์™œ๋ƒํ•˜๋ฉด ๋งŽ์€ ์ด์šฉ์ž๊ฐ€ ์š”์ฒญํ–ˆ์„ ๋•Œ, ์ค‘๋ณต๋˜๋Š” ์ผ์‹œ๊ฐ€ ๋งŽ์„ ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ์ด๊ณ , ๊ทธ๋žฌ์„ ๋•Œ, max()๋ฅผ ์“ฐ์ง€ ์•Š์œผ๋ฉด ์—ฌ๋Ÿฌ PK ๊ฐ’์ด ์กฐํšŒ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

์ฃผ๋‹ˆ๋Š” data_created_date_time ํ…Œ์ด๋ธ”์—์„œ ํŠน์ • ๋‚ ์งœ์™€ ์‹œ๊ฐ„์— ํ•ด๋‹นํ•˜๋Š” data_created_date์™€ data_created_time์˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋“ค ์ค‘์—์„œ data_created_date_time_id ์—ด์˜ ์ตœ๋Œ€๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์–ด ์œ„์™€ ๊ฐ™์ด SQL๋ฌธ์„ ์ž‘์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.

์ด ๋•Œ, #{createdDate}์™€ #{createdTime}์€ SQL ์ฟผ๋ฆฌ์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์‹ค์ œ ์‹คํ–‰๋  ๋•Œ, ์ด๋Ÿฌํ•œ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‹ค์ œ ๊ฐ’์œผ๋กœ ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๊ณ , ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋™์ ์œผ๋กœ ์›ํ•˜๋Š” ๋‚ ์งœ์™€ ์‹œ๊ฐ„์— ํ•ด๋‹นํ•˜๋Š” PK์˜ ์ตœ๋Œ€๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”.

๊ฒฐ๊ณผ์ ์œผ๋กœ createdDate๊ฐ€ 2023-07-16์ด๊ณ , createdTime์ด 12:00:00๋ผ๊ณ  ๊ฐ€์ •ํ•  ๋•Œ, ํ•ด๋‹น ์ฟผ๋ฆฌ๋Š” "2023-07 -16" ๋‚ ์งœ์™€ "12:00:00" ์‹œ๊ฐ„์— ํ•ด๋‹นํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋“ค ์ค‘์—์„œ PK ๊ฐ’์˜ ์ตœ๋Œ€๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋  ๊ฑฐ์—์š”.

 

ConnectedUserInfoServiceImpl 199 ~ 229 ๋ฒˆ์งธ ์ค„


๋‹ค์‹œ ์ด ๊ณณ์œผ๋กœ ๋Œ์•„์™€์„œ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒ๋œ PK๊ฐ’์ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๊ณ , ์—†๋‹ค๋ฉด ํ•ด๋‹น ์ ‘์† ์ผ์‹œ๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด ์ฃผ์—ˆ์–ด์š”.

์œ„์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ €์žฅ ์„ฑ๊ณตํ•˜๋ฉด ์ €์žฅ ๋ ˆ์ฝ”๋“œ์˜ PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์กฐํšŒ ์‹œ PK ๊ฐ’์ด ์žˆ์—ˆ์„ ๋• ๊ทธ PK ๊ฐ’์ด ๋ฐ˜ํ™˜ ๋˜๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.

 

OccurrenceDataDateTimeManagementDao save()



OccurrenceDataDateTimeManagementDaoImpl save()


์ฐธ๊ณ ๋กœ DAO์—์„œ ํ•œ๊ฐ€์ง€ ๋กœ์ง์ด ์žˆ๋Š”๋ฐ, ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅํ•œ ๋’ค ๋ฐ˜ํ™˜๋œ PK ๊ฐ’์ด Null์ด๊ฑฐ๋‚˜, 0์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ , ์•„๋‹ˆ๋ผ๋ฉด DataCreatedDateTimeVo์— ์ €์žฅ๋œ PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ด ์ฃผ์—ˆ๊ณ , ๋งž๋‹ค๋ฉด Custom Exception์ด ํ„ฐ์ง€๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.

 

OccurrenceDataDateTimeManagementMapper save()



OccurenceDataDateTimeManagementMapper.xml


์„œ๋ฒ„ ์ €์žฅ๋•Œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ PK ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๋„๋ก ํ•˜๋ฉด์„œ ์ ‘์† ์ผ์‹œ๊ฐ€ ์ €์žฅ๋˜๋„๋ก ํ•ด ์ฃผ์—ˆ๋Š”๋ฐ, 16๋ฒˆ์งธ ์ค„ ๋ถ€ํ„ฐ 18๋ฒˆ์งธ ์ค„์— ๋‚ด์šฉ์€ MyBatis๋ฅผ ์ด์šฉํ•ด์„œ ์ƒˆ๋กœ์šด ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์‚ฝ์ž…ํ•  ๋•Œ, ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ PK ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์ž‘์„ฑํ•œ ๋ถ€๋ถ„์ด์—์š”.

โˆ™ <selectKey>: MyBatis์˜ SQL ๋งคํผ์—์„œ ์ž๋™ ์ƒ์„ฑ๋œ PK ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํƒœ๊ทธ.
                            INSERT ๋ฌธ ์‹คํ–‰ ๋’ค ํŠน์ • SQL๋ฌธ์„ ์‹คํ–‰ํ•˜์—ฌ ์ž๋™ ์ƒ์„ฑ๋œ PK ๊ฐ’ ์กฐํšŒ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ.
โˆ™ keyProperty: ์ด ์†์„ฑ์€ ๊ฐ€์ ธ์˜จ PK ๊ฐ’์„ ๋งคํ•‘ํ•  ์ž๋ฐ” ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ ์ง€์ •.
โˆ™ resultType: ๊ฐ€์ ธ์˜จ PK ๊ฐ’์„ ๋งคํ•‘ํ•  ์ž๋ฐ” ๊ฐ์ฒด ๋ฐ์ดํ„ฐ ํƒ€์ž… ์ง€์ •.
                        ์œ„ ์ฝ”๋“œ์—์„œ๋Š” java.lang.Long ์ฆ‰, Long wrapper ์ž๋ฃŒํ˜• ํƒ€์ž…์œผ๋กœ PK ๊ฐ’ ๋ฐ˜ํ™˜.
โˆ™ order="AFTER": ์ด ์†์„ฑ์€ ์ž๋™ ์ƒ์„ฑ๋œ PK ๊ฐ’์„ ์กฐํšŒํ•˜๋Š” SQL ๋ฌธ ์‹คํ–‰ ์ˆœ์„œ ์ง€์ •.
                                 AFTER ์„ค์ • ์‹œ INSERT ๋ฌธ์ด ์‹คํ–‰๋œ ๋’ค์— SELECT LAST_INSERT_ID() ์‹คํ–‰.
โˆ™ SELECT LAST_INSERT_ID(): MySQL ๊ณ„์—ด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—์„œ ์ž๋™ ์ƒ์„ฑ๋œ PK ๊ฐ’ ์กฐํšŒ ํ•จ์ˆ˜.
                                                      LAST_INSERT_ID()๋Š” ์ง์ „ ์‚ฝ์ž…๋œ ์ž๋™ ์ƒ์„ฑ๋œ PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ,
                                                      ์ด ๊ฐ’์€ ์ฃผ๋กœ AUTO_INCREMENT ๋“ฑ๊ณผ ๊ฐ™์€ ์ž๋™ ์ฆ๊ฐ€ ํ‚ค๋ฅผ ๊ฐ€์ง„ ํ…Œ์ด๋ธ”์—์„œ ์‚ฌ์šฉ.

 

 

 

processUserInfoSave()

์ด๋ฒˆ์—๋Š” ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•ด ๋ถ„์„ํ•ด ๋ณผ๊ฒŒ์š”.

ConnetedUserInfoServiceImpl 231 ~ 266๋ฒˆ์งธ ์ค„


ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋Š” ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋‹ด์€ ConnectedUserInfoSaveRequestDto ๊ฐ์ฒด์™€ ๋‚ด๋ถ€ ์„œ๋ฒ„ ์ •๋ณด PK ๊ฐ’, ์ ‘์† ์ผ์‹œ PK๊ฐ’์„ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋ฐ›๊ณ  ์žˆ์–ด์š”.

242 ~ 251๋ฒˆ์งธ ์ค„๊นŒ์ง€ ๊ฐ๊ฐ์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์— ๋Œ€ํ•œ Null Check๋ฅผ ์ง„ํ–‰ํ•˜๊ณ , Null์ด ์•„๋‹ˆ๋ผ๋ฉด 252๋ฒˆ์งธ ์ค„ ๋ถ€ํ„ฐ ๋กœ์ง์ด ์ง„ํ–‰๋˜์š”.

 ์ตœ์ดˆ ์ด์šฉ์ž IP๋ฅผ ์ด์šฉํ•ด์„œ ํ•ด๋‹น ์ด์šฉ์ž ์ •๋ณด๊ฐ€ ์ด๋ฏธ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅ ๋˜์–ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด ์ฃผ์—ˆ์–ด์š”.
์ด ๋•Œ,  ์ „๋‹ฌ๋œ IP ๋ฌธ์ž์—ด์— Double Quotation(์Œ ๋”ฐ์˜ดํ‘œ)์— ๊ฐ์‹ธ์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ํŠน์ˆ˜๋ฌธ์ž๋ฅผ ์ง€์šฐ๊ธฐ ์œ„ํ•ด replace()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

 

UserInfoDatoImpl findByUserIP()



UserManagementMapper findByUserIP()


์œ„์™€ ๊ฐ™์ด ์ด์šฉ์ž IP ์ฃผ์†Œ๋ฅผ ํ†ตํ•ด์„œ conneted_user ํ…Œ์ด๋ธ”์— ๊ฐ’์„ ์กฐํšŒํ•˜๋Š”๋ฐ, ์ด ๋•Œ, PK ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ฒŒ ํ•˜๊ณ , ๋™์ผ IP๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ์กฐํšŒ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งˆ์ง€๋ง‰ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด max()๋ฅผ ์‚ฌ์šฉํ•ด ์ฃผ์—ˆ์–ด์š”.

์ด๋ ‡๊ฒŒ ์กฐํšŒ๋œ PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ด ์ฃผ์—ˆ๋‹ต๋‹ˆ๋‹ค.

 

ConnetedUserInfoServiceImpl 231 ~ 266๋ฒˆ์งธ ์ค„

 

๋‹ค์‹œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋ถ€๋ถ„์„ ๋ณด๋ฉด 256๋ฒˆ์งธ ์ค„์— if๋ฌธ์„ ํ†ตํ•ด ์ด์šฉ์ž IP๋ฅผ ์ด์šฉํ•ด์„œ ์กฐํšŒ๋œ PK ๊ฐ’์ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๊ณ , ์—†๋‹ค๋ฉด ConnectedUserInfoSaveRequestDto์— ์ €์žฅ๋œ ์ •๋ณด๋ฅผ ์•”ํ˜ธํ™” ํ•˜์—ฌ ConnectedUserInfoVo.toVo()๋ฅผ ํ†ตํ•ด Value Object๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ์ด๋ฅผ UserInfoDAO์˜ connectedUserSave()์— ์ „๋‹ฌํ•ด ์ฃผ์—ˆ๊ณ , ์ €์žฅ์ด ์™„๋ฃŒ๋˜๋ฉด ๋ฐ˜ํ™˜๋œ PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.

UserInfoDaoImpl connectedUserSave()

 

UserManagementMapper connectedUserSave()

 

UserManagementMapper.xml 1 ~ 19๋ฒˆ์งธ ์ค„


์œ„์™€ ๊ฐ™์ด ์ ‘์† ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.



ConnectedUserInfoServiceImpl 268 ~ 278๋ฒˆ์งธ ์ค„


๋งŒ์•ฝ ์ด์šฉ์ž ์ ‘์† IP๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒํ–ˆ์„ ๋•Œ, ๊ฐ’์ด ์กฐํšŒ๋œ๋‹ค๋ฉด ํ•ด๋‹น else ์ ˆ์„ ํƒ€๊ฒŒ ๋˜๊ณ , ์ด ๋•Œ๋Š” ๊ธฐ์กด์— ์ €์žฅ ๋˜์–ด ์žˆ๋˜ ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ Update ํ•˜๊ธฐ ์œ„ํ•œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด ๋‘์—ˆ์–ด์š”.

์ตœ์ดˆ UpdateUserInfo ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ, ์ด ๋•Œ, ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒ๋œ ์ด์šฉ์ž IP ์ฃผ์†Œ์— ํ•ด๋‹น ํ•˜๋Š” PK ๊ฐ’๊ณผ ์ ‘์† ์ผ์‹œ ์ €์žฅ PK ๊ฐ’์„ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋ฆฌ๊ณ , ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ๋กœ์ง์ด ๋๋‚˜๋ฉด ํ•ด๋‹น PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.



UpdateUserInfo.java


์œ„ ํด๋ž˜์Šค๋Š” ์ด์šฉ์ž ์ ‘์† ์ •๋ณด์— ๋Œ€ํ•œ PK ๊ฐ’๊ณผ ์ ‘์† ์ผ์‹œ PK ๊ฐ’์„ ๋‹ด๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์—์š”.

์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ UpdateUserInfo ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—์„œ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋งค๊ฐœ ๋ณ„์ˆ˜๋กœ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์–ด์š”.



UserInfoDaoImpl updateCount()


ํ•ด๋‹น ๋กœ์ง์€ ๋™์ผ ์ •๋ณด๋กœ ์š”์ฒญ์„ ๋‚ ๋ฆฐ ์ด์šฉ์ž๊ฐ€ ์žˆ์„ ๋•Œ, ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ค‘๋ณต ์ €์žฅํ•˜์ง€ ์•Š๊ณ , ์ ‘์† ํšŸ์ˆ˜๋ฅผ ์นด์šดํŠธํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด์—์š”.

Mapper๋ฅผ ํ†ตํ•ด ๋ฐ˜ํ™˜๋œ Update๋œ ๋ฐ์ดํ„ฐ PK ๊ฐ’์ด Null์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ , Null์ด ์•„๋‹ˆ๋ฉด ํ•ด๋‹น PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด ์ค๋‹ˆ๋‹ค.


UserManagementMapper updateCount()



UserManagementMapper.xml 43 ~ 53๋ฒˆ์งธ ์ค„


์œ„์™€ ๊ฐ™์ด Update SQL๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ updateUserInfo ๊ฐ์ฒด์— ๋‹ด๊ธด ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด PK ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” connected_user_count ๋ ˆ์ฝ”๋“œ๋ฅผ 1 ์ฆ๊ฐ€ ์‹œ์ผœ ์ฃผ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค 48๋ฒˆ์งธ ์ค„์—์„œ updateUserInfo ๊ฐ์ฒด์— ์ €์žฅ๋œ ์ ‘์† ์ผ์‹œ๊ฐ€ Null ์ด๊ฑฐ๋‚˜, ๋น„์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์•„๋‹ˆ๋ผ๋ฉด ๋งˆ์ง€๋ง‰ ์ ‘์† ์ผ์‹œ ์ •๋ณด๋กœ ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ ์œ„ํ•ด data_created_date_time_id ๋ ˆ์ฝ”๋“œ ๊ฐ’์„ ์ƒˆ๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์œผ๋กœ ๋ฐ”๊ฟ” ์ฃผ์—ˆ์–ด์š”. 

 

 

 

processUserRequestInfoSave()

๋งˆ์ง€๋ง‰์œผ๋กœ ์š”์ฒญ ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด ์ €์žฅ์„ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•ด ๋ถ„์„ํ•ด ๋ณผ๊ฒŒ์š”.

ConnectedUserInfoServiceImpl 280 ~ 317 ๋ฒˆ์งธ


ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋Š” ์š”์ฒญ ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด๋ฅผ ๋‹ด์€ Dto์™€ ์ด์šฉ์ž ์š”์ฒญ ์ผ์‹œ PK ๊ฐ’, ์ ‘์† ์ด์šฉ์ž ์ •๋ณด PK ๊ฐ’์„ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋ฐ›๊ณ  ์žˆ์–ด์š”.

290 ~ 302๋ฒˆ์งธ ์ค„๊นŒ์ง€ ๊ฐ๊ฐ์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด Null Check๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜๊ณ , Null์ด ์•„๋‹ˆ๋ผ๋ฉด 302๋ฒˆ์งธ ์ค„์— else ์ ˆ์„ ํƒ€๊ฒŒ ๋˜์š”.

๊ทธ๋Ÿฐ ๋’ค ๋‚ด๋ถ€ ์„œ๋ฒ„ ์ •๋ณด PK ๊ฐ’, ์ด์šฉ์ž ์š”์ฒญ ์ผ์‹œ ์ •๋ณด PK ๊ฐ’, ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด PK ๊ฐ’, ์š”์ฒญ ํ—ค๋”, ์ฟ ํ‚ค, ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ, ์š”์ฒญ ๋ฐ”๋””๊ฐ’์„ ConnectedUserRequestInfoSaveRequestDto์— ๋‹ด๊ณ , 305๋ฒˆ์งธ ์ค„์— ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์ €์žฅ์„ ์œ„ํ•ด Value Object๋กœ ๋ณ€ํ™˜ํ•œ ๋’ค ์ด๋ฅผ DAO์˜ findByRequestInfoSave()๋กœ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์–ด์š”.


UserInfoDaoImpl findByRequestInfoSave()



UserManagementMapper findByRequestInfoSave()

 

 

์œ„์™€ ๊ฐ™์ด Insert ๋ฌธ์„ ์ด์šฉํ•ด์„œ ์ €์žฅํ•ด ์ค€ ๋’ค ์ €์žฅ๋œ ๋ ˆ์ฝ”๋“œ์˜ PK ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.

 

 

 

 

 

    ๐Ÿ”ฝ  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๋ถ„์„

        ๐Ÿ“ฆ ConnectedUserInfoControllerTest

์œ„์—์„œ ์ž‘์„ฑํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณผ๊ฒŒ์š”.

package com.giggalpeople.backoffice.api.user.service.impl;

import static com.giggalpeople.backoffice.api.user.model.dto.enumtype.UserInfoSearchType.CONNECTED_USER_REQUEST_ID;
import static com.giggalpeople.backoffice.common.enumtype.CrewGrade.GENERAL_CREW;
import static com.giggalpeople.backoffice.common.enumtype.CrewGrade.TEAM_LEADER;
import static com.giggalpeople.backoffice.common.enumtype.ErrorCode.NOT_EXIST_CONNECTED_USER;
import static com.giggalpeople.backoffice.common.enumtype.ErrorCode.NO_AUTHORIZATION;
import static com.giggalpeople.backoffice.common.enumtype.ErrorCode.PARAMETER_NULL;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;

import com.giggalpeople.backoffice.api.common.database.dao.OccurrenceDataDateTimeManagementDao;
import com.giggalpeople.backoffice.api.common.model.Criteria;
import com.giggalpeople.backoffice.api.common.model.dto.request.DataCreatedDateTimeRequestDto;
import com.giggalpeople.backoffice.api.common.model.vo.DataCreatedDateTimeVo;
import com.giggalpeople.backoffice.api.server.database.dao.ServerInfoDao;
import com.giggalpeople.backoffice.api.server.model.dto.request.ServerInfoSaveRequestDto;
import com.giggalpeople.backoffice.api.server.model.vo.ServerInfoVo;
import com.giggalpeople.backoffice.api.user.database.dao.UserInfoDao;
import com.giggalpeople.backoffice.api.user.exception.ConnectedUserException;
import com.giggalpeople.backoffice.api.user.model.dto.enumtype.UserInfoSearchType;
import com.giggalpeople.backoffice.api.user.model.dto.request.ConnectedUserInfoSaveRequestDto;
import com.giggalpeople.backoffice.api.user.model.dto.request.UserInfoDetailSearchRequestDto;
import com.giggalpeople.backoffice.api.user.model.dto.request.UserInfoSearchDto;
import com.giggalpeople.backoffice.api.user.model.dto.request.UserRequestTotalInfoSaveRequestDto;
import com.giggalpeople.backoffice.api.user.model.dto.response.UserInfoDetailResponseDto;
import com.giggalpeople.backoffice.api.user.model.dto.response.UserInfoListResponseDto;
import com.giggalpeople.backoffice.api.user.model.vo.ConnectedUserInfoVo;
import com.giggalpeople.backoffice.api.user.request_info.model.dto.request.ConnectedUserRequestInfoSaveRequestDto;
import com.giggalpeople.backoffice.api.user.request_info.model.vo.UserRequestInfoVo;
import com.giggalpeople.backoffice.api.user.service.ConnectedUserInfoService;
import com.giggalpeople.backoffice.common.constant.DefaultListResponse;
import com.giggalpeople.backoffice.common.constant.DefaultResponse;
import com.giggalpeople.backoffice.common.database.DataBaseManagerMapper;
import com.giggalpeople.backoffice.common.entity.ServerInfo;
import com.giggalpeople.backoffice.common.enumtype.GiggalPeopleServerNames;
import com.giggalpeople.backoffice.common.env.exception.ServerInfoException;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@ExtendWith(SpringExtension.class)
@SpringBootTest
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:/init/database/schema.sql")
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:/init/database/data.sql")
class ConnectedUserInfoServiceImplTest {

	@Autowired
	ConnectedUserInfoService connectedUserInfoService;

	@Autowired
	UserInfoDao userInfoDAO;

	@Autowired
	ServerInfoDao serverInfoDAO;

	@Autowired
	OccurrenceDataDateTimeManagementDao occurrenceDataDateTimeManagementDAO;

	@Autowired
	DataBaseManagerMapper dataBaseManagerMapper;

	DataCreatedDateTimeVo dataCreatedDateTimeVo;

	ServerInfo serverInfo;
	ServerInfoVo serverInfoVo;

	ConnectedUserInfoVo userInfoVO;

	UserInfoSearchDto searchForUserId;

	UserInfoSearchDto searchForUserConnectedDateRange;

	UserInfoSearchDto searchForUserConnectedDate;

	UserInfoSearchDto searchForServerName;

	UserInfoSearchDto searchForServerIp;

	UserInfoSearchDto searchForUserIp;

	DataCreatedDateTimeRequestDto dataCreatedDateTimeRequestDto;

	ServerInfoSaveRequestDto serverInfoSaveRequestDto;

	ConnectedUserInfoSaveRequestDto connectedUserInfoSaveRequestDto;

	ConnectedUserRequestInfoSaveRequestDto connectedUserRequestInfoSaveRequestDto;

	UserRequestInfoVo userRequestInfoVo;

	UserRequestTotalInfoSaveRequestDto userRequestTotalInfoSaveRequestDto;

	UserInfoDetailSearchRequestDto userInfoDetailSearchRequestDto;

	Criteria criteria;

	List<UserInfoListResponseDto> userInfoList;

	@BeforeEach
	void beforeTestSetup() {
		this.userRequestTotalInfoSaveRequestDto = initializedMockModels();

		initializedMockSearchRequestDto();
	}

	/**
	 * <b>๊ฐ€์งœ ๊ฒ€์ƒ‰ ์š”์ฒญ DTO๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method</b>
	 */
	private void initializedMockSearchRequestDto() {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String[] splitNowDateTime = simpleDateFormat.format(new Date(System.currentTimeMillis())).split(" ");

		initializedMockSearchUserIdRequestDto();
		initializedMockSearchUserConnectedDateRangeRequestDto(splitNowDateTime[0]);
		initializedMockSearchUserConnectedDateRequestDto(splitNowDateTime[0]);
		initializedMockSearchServerNameRequestDto();
		initializedMockSearchServerIpRequestDto();
		initializedMockSearchUserIpRequestDto();
		initializedMockDetailRequestDto();
		initializedMockCriteria();
		initializedMockUserInfo(splitNowDateTime);
	}

	@Test
	@Order(0)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด Data Base ์ €์žฅ ํ…Œ์ŠคํŠธ")
	void save() {
		//given
		DefaultResponse<Map<String, Long>> responseInfo = connectedUserInfoService.save(
			userRequestTotalInfoSaveRequestDto);

		//when
		System.out.println("์‘๋‹ต ๊ฐ’ : " + responseInfo);

		//then
		assertThat(responseInfo.getStatusCode()).isEqualTo(201);
		assertThat(responseInfo.getMessage()).isEqualTo("์ƒ์„ฑ ์„ฑ๊ณต");
	}

	@Test
	@Order(1)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด Data Base ์ €์žฅ ์‹œ ๋‚ด๋ถ€ ์„œ๋ฒ„ ์ •๋ณด Null ๊ฐ’ ์ž…๋ ฅ์œผ๋กœ ์ธํ•œ ๋ฌธ์ œ ํ…Œ์ŠคํŠธ")
	void causedByServerInfoSaveFailure() {
		//given
		UserRequestTotalInfoSaveRequestDto userRequestTotalInfoSaveRequestErrorStatusDto = createErrorStatusDto(
			"serverInfo");
		//when
		ServerInfoException serverInfoException = assertThrows(ServerInfoException.class, () -> {
			connectedUserInfoService.save(
				userRequestTotalInfoSaveRequestErrorStatusDto);
		});

		// then
		assertEquals(PARAMETER_NULL.getMessage(String.valueOf(NullPointerException.class)),
			serverInfoException.getMessage());
	}

	@Test
	@Order(2)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด Data Base ์ €์žฅ ์‹œ Data ๋ฐœ์ƒ ์ผ์‹œ Null ๊ฐ’ ์ž…๋ ฅ์œผ๋กœ ์ธํ•œ ๋ฌธ์ œ ํ…Œ์ŠคํŠธ")
	void causedByOccurrenceDateTimeSaveFailure() {
		//given
		UserRequestTotalInfoSaveRequestDto userRequestTotalInfoSaveRequestErrorStatusDto = createErrorStatusDto(
			"occurrenceDateTime");
		//when
		ConnectedUserException connectedUserException = assertThrows(ConnectedUserException.class, () -> {
			connectedUserInfoService.save(
				userRequestTotalInfoSaveRequestErrorStatusDto);
		});

		// then
		assertEquals(PARAMETER_NULL.getMessage(String.valueOf(NullPointerException.class)),
			connectedUserException.getMessage());
	}

	@Test
	@Order(3)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด Data Base ์ €์žฅ ์‹œ ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด Null๋กœ ์ธํ•œ ๋ฌธ์ œ ํ…Œ์ŠคํŠธ")
	void causedByUserInfoSaveFailure() {
		//given
		UserRequestTotalInfoSaveRequestDto userRequestTotalInfoSaveRequestErrorStatusDto = createErrorStatusDto(
			"userInfo");
		//when
		ConnectedUserException connectedUserException = assertThrows(ConnectedUserException.class, () -> {
			connectedUserInfoService.save(
				userRequestTotalInfoSaveRequestErrorStatusDto);
		});

		// then
		assertEquals(PARAMETER_NULL.getMessage(String.valueOf(NullPointerException.class)),
			connectedUserException.getMessage());
	}

	@Test
	@Order(4)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด Data Base ์ €์žฅ ์‹œ ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด Null๋กœ ์ธํ•œ ๋ฌธ์ œ ํ…Œ์ŠคํŠธ")
	void causedByUserRequestInfoSaveFailure() {
		//given
		UserRequestTotalInfoSaveRequestDto userRequestTotalInfoSaveRequestErrorStatusDto = createErrorStatusDto(
			"userInfo");
		//when
		ConnectedUserException connectedUserException = assertThrows(ConnectedUserException.class, () -> {
			connectedUserInfoService.save(
				userRequestTotalInfoSaveRequestErrorStatusDto);
		});

		// then
		assertEquals(PARAMETER_NULL.getMessage(String.valueOf(NullPointerException.class)),
			connectedUserException.getMessage());
	}

	@Test
	@Order(5)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด Data Base ์ €์žฅ ์‹œ ์ €์žฅ DTO ๊ฐ’ Null ์ผ ๊ฒฝ์šฐ ๋ฌธ์ œ ํ…Œ์ŠคํŠธ")
	void saveNotNull() {
		//given
		//when
		ConnectedUserException connectedUserException = Assertions.assertThrows(ConnectedUserException.class,
			() -> connectedUserInfoService.save(null));

		//then
		assertEquals(PARAMETER_NULL.getMessage(), connectedUserException.getMessage());
	}

	@Test
	@Order(6)
	@DisplayName("Application ์š”์ฒญ ์ด์šฉ์ž ๋ฐ ์š”์ฒญ ์ •๋ณด ๊ธฐ๋ณธ ๋ชฉ๋ก ์กฐํšŒ ํ…Œ์ŠคํŠธ")
	@Transactional
	void toDiscordAllUserInfoFind() {
		//given
		IntStream.rangeClosed(1, 11).forEach(count -> {
			System.out.println(
				"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(userRequestTotalInfoSaveRequestDto));
		});

		UserInfoSearchDto userInfoSearchDto = new UserInfoSearchDto();
		userInfoSearchDto.setInputSearchType(null);
		userInfoSearchDto.setSearchWord(null);

		//when
		DefaultListResponse<List<UserInfoListResponseDto>> responseInfo = connectedUserInfoService.toDiscordAllUserInfoFind(
			criteria, userInfoSearchDto);

		//then
		System.out.println("Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ : " + responseInfo.getPagination());
		System.out.println("Data Base์—์„œ ์ฐพ์€ Data ๋‚ด์—ญ : " + responseInfo.getData());
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
	}

	@Test
	@Order(7)
	@DisplayName("Application ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ๊ธฐ๋ณธ ๋ชฉ๋ก ์กฐํšŒ ์‹œ ๊ฒฐ๊ณผ ํ•˜๋‚˜ ํ…Œ์ŠคํŠธ")
	@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:/init/database/schema.sql")
	void toDiscordAllUserInfoFindOneThing() {
		//given
		dataBaseManagerMapper.initializeAutoIncrement("log");
		dataBaseManagerMapper.initializeAutoIncrement("connected_user_request_info");
		dataBaseManagerMapper.initializeAutoIncrement("connected_user");
		dataBaseManagerMapper.initializeAutoIncrement("server_info");
		dataBaseManagerMapper.initializeAutoIncrement("data_created_date_time");

		System.out.println(
			"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(userRequestTotalInfoSaveRequestDto));

		UserInfoSearchDto userInfoSearchDto = new UserInfoSearchDto();
		userInfoSearchDto.setInputSearchType(null);
		userInfoSearchDto.setSearchWord(null);

		//when
		DefaultListResponse<List<UserInfoListResponseDto>> responseInfo = connectedUserInfoService.toDiscordAllUserInfoFind(
			criteria, userInfoSearchDto);

		//then
		System.out.println("Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ : " + responseInfo.getPagination());
		System.out.println("Data Base์—์„œ ์ฐพ์€ Data ๋‚ด์—ญ : " + responseInfo.getData());
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
	}

	@Test
	@Order(8)
	@DisplayName("Application ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด Paging ์ฒ˜๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ ํ…Œ์ŠคํŠธ")
	@Transactional
	void toDiscordAllUserInfoFindPaging() {
		//given
		IntStream.rangeClosed(1, 11).forEach(count -> {
			System.out.println(
				"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(userRequestTotalInfoSaveRequestDto));
		});

		Criteria requestPaging = new Criteria();
		requestPaging.setPage(3);
		requestPaging.setPerPageNum(5);

		UserInfoSearchDto userInfoSearchDto = new UserInfoSearchDto();
		userInfoSearchDto.setInputSearchType(null);
		userInfoSearchDto.setSearchWord(null);

		//when
		DefaultListResponse<List<UserInfoListResponseDto>> responseInfo = connectedUserInfoService.toDiscordAllUserInfoFind(
			requestPaging, userInfoSearchDto);

		//then
		System.out.println("Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ : " + responseInfo.getPagination());
		System.out.println("Data Base์—์„œ ์ฐพ์€ Data ๋‚ด์—ญ : " + responseInfo.getData());
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
		assertThat(responseInfo.getPagination().getCriteria().getPage()).isEqualTo(3);
		assertThat(responseInfo.getPagination().getCriteria().getPerPageNum()).isEqualTo(5);
		assertThat(responseInfo.getPagination().getTotalCount()).isEqualTo(11);
	}

	@Test
	@Order(9)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ ์‹œ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์—†์„ ๋•Œ, ๋ฌธ์ œ ์‚ฌํ•ญ ํ…Œ์ŠคํŠธ")
	@Transactional
	@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:/init/database/schema.sql")
	void totalSearchNotFound() {
		//given
		dataBaseManagerMapper.initializeAutoIncrement("log");
		dataBaseManagerMapper.initializeAutoIncrement("connected_user_request_info");
		dataBaseManagerMapper.initializeAutoIncrement("connected_user");
		dataBaseManagerMapper.initializeAutoIncrement("server_info");
		dataBaseManagerMapper.initializeAutoIncrement("data_created_date_time");

		UserInfoSearchDto userInfoSearchDto = new UserInfoSearchDto();
		userInfoSearchDto.setInputSearchType(null);
		userInfoSearchDto.setSearchWord(null);

		//when
		ConnectedUserException connectedUserException = Assertions.assertThrows(ConnectedUserException.class,
			() -> connectedUserInfoService.toDiscordAllUserInfoFind(criteria, userInfoSearchDto));

		//then
		assertEquals(NOT_EXIST_CONNECTED_USER.getMessage(), connectedUserException.getMessage());
	}

	@Test
	@Order(10)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ ์‹œ ์ด์šฉ์ž ์ˆœ์„œ ๋ฒˆํ˜ธ๋ฅผ ํ†ตํ•ด ๊ฒ€์ƒ‰ ํ…Œ์ŠคํŠธ")
	void totalUserInfoIdSearch() {
		//given
		IntStream.rangeClosed(1, 11).forEach(count -> {
			System.out.println(
				"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(userRequestTotalInfoSaveRequestDto));
		});

		//when
		DefaultListResponse<List<UserInfoListResponseDto>> responseInfo = connectedUserInfoService.toDiscordAllUserInfoFind(
			criteria, searchForUserId);

		//then
		System.out.println("Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ : " + responseInfo.getPagination());
		System.out.println("Data Base์—์„œ ์ฐพ์€ Data ๋‚ด์—ญ : " + responseInfo.getData());
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
	}

	@Test
	@Order(11)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ ์‹œ ์ ‘์†์ผ ๋ฒ”์œ„๋ฅผ ํ†ตํ•ด ๊ฒ€์ƒ‰ ํ–ˆ์„ ๋•Œ, ์ผ์น˜ํ•˜๋Š” Data๊ฐ€ ๋ช‡ ๊ฐœ ์žˆ๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•œ ํ…Œ์ŠคํŠธ")
	void totalUserInfoConnectedDateRangeSearchCount() {
		//given
		IntStream.rangeClosed(1, 11).forEach(count -> {
			System.out.println(
				"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(userRequestTotalInfoSaveRequestDto));
		});

		//when
		DefaultListResponse<List<UserInfoListResponseDto>> responseInfo = connectedUserInfoService.toDiscordAllUserInfoFind(
			criteria, searchForUserConnectedDateRange);

		//then
		System.out.println("Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ : " + responseInfo.getPagination());
		System.out.println("Data Base์—์„œ ์ฐพ์€ Data ๋‚ด์—ญ : " + responseInfo.getData());
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
	}

	@Test
	@Order(12)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ ์‹œ ์ ‘์†์ผ ๊ฒ€์ƒ‰ ํ–ˆ์„ ๋•Œ, ์ผ์น˜ํ•˜๋Š” Data๊ฐ€ ๋ช‡ ๊ฐœ ์žˆ๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•œ ํ…Œ์ŠคํŠธ")
	void totalUserInfoConnectedDateSearchCount() {
		//given
		IntStream.rangeClosed(1, 11).forEach(count -> {
			System.out.println(
				"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(userRequestTotalInfoSaveRequestDto));
		});

		//when
		DefaultListResponse<List<UserInfoListResponseDto>> responseInfo = connectedUserInfoService.toDiscordAllUserInfoFind(
			criteria, searchForUserConnectedDate);

		//then
		System.out.println("Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ : " + responseInfo.getPagination());
		System.out.println("Data Base์—์„œ ์ฐพ์€ Data ๋‚ด์—ญ : " + responseInfo.getData());
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
	}

	@Test
	@Order(13)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ ์‹œ ๋‚ด๋ถ€ ์„œ๋ฒ„ ์ด๋ฆ„ ๊ฒ€์ƒ‰ ํ–ˆ์„ ๋•Œ, ์ผ์น˜ํ•˜๋Š” Data๊ฐ€ ๋ช‡ ๊ฐœ ์žˆ๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•œ ํ…Œ์ŠคํŠธ")
	void totalUserInfoServerNameSearchCount() {
		//given
		IntStream.rangeClosed(1, 11).forEach(count -> {
			System.out.println(
				"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(userRequestTotalInfoSaveRequestDto));
		});

		//when
		DefaultListResponse<List<UserInfoListResponseDto>> responseInfo = connectedUserInfoService.toDiscordAllUserInfoFind(
			criteria, searchForServerName);

		//then
		System.out.println("Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ : " + responseInfo.getPagination());
		System.out.println("Data Base์—์„œ ์ฐพ์€ Data ๋‚ด์—ญ : " + responseInfo.getData());
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
	}

	@Test
	@Order(14)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ ์‹œ ๋‚ด๋ถ€ ์„œ๋ฒ„ IP ๊ฒ€์ƒ‰ ํ–ˆ์„ ๋•Œ, ์ผ์น˜ํ•˜๋Š” Data๊ฐ€ ๋ช‡ ๊ฐœ ์žˆ๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•œ ํ…Œ์ŠคํŠธ")
	void totalUserInfoServerIpSearchCount() {
		//given
		IntStream.rangeClosed(1, 11).forEach(count -> {
			System.out.println(
				"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(userRequestTotalInfoSaveRequestDto));
		});

		//when
		DefaultListResponse<List<UserInfoListResponseDto>> responseInfo = connectedUserInfoService.toDiscordAllUserInfoFind(
			criteria, searchForServerIp);

		//then
		System.out.println("Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ : " + responseInfo.getPagination());
		System.out.println("Data Base์—์„œ ์ฐพ์€ Data ๋‚ด์—ญ : " + responseInfo.getData());
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
	}

	@Test
	@Order(9)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ ์‹œ ์ด์šฉ์ž IP ๊ฒ€์ƒ‰ ํ–ˆ์„ ๋•Œ, ์ผ์น˜ํ•˜๋Š” Data๊ฐ€ ๋ช‡ ๊ฐœ ์žˆ๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•œ ํ…Œ์ŠคํŠธ")
	void totalUserInfoUserIpSearchCount() {
		//given
		System.out.println(
			"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(
				userRequestTotalInfoSaveRequestDto));

		//when
		DefaultListResponse<List<UserInfoListResponseDto>> responseInfo = connectedUserInfoService.toDiscordAllUserInfoFind(
			criteria, this.searchForUserIp);

		//then
		System.out.println("Paging ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ : " + responseInfo.getPagination());
		System.out.println("Data Base์—์„œ ์ฐพ์€ Data ๋‚ด์—ญ : " + responseInfo.getData());
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
	}

	@Test
	@Order(15)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ๊ฒ€์ƒ‰ ๋ชฉ๋ก ์กฐํšŒ ์‹œ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์—†์„ ๋•Œ, ๋ฌธ์ œ ์‚ฌํ•ญ ํ…Œ์ŠคํŠธ")
	@Transactional
	@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:/init/database/schema.sql")
	void totalUserInfoSearchNotFound() {
		//given
		dataBaseManagerMapper.initializeAutoIncrement("log");
		dataBaseManagerMapper.initializeAutoIncrement("connected_user_request_info");
		dataBaseManagerMapper.initializeAutoIncrement("connected_user");
		dataBaseManagerMapper.initializeAutoIncrement("server_info");
		dataBaseManagerMapper.initializeAutoIncrement("data_created_date_time");

		//when
		ConnectedUserException connectedUserException = Assertions.assertThrows(ConnectedUserException.class,
			() -> connectedUserInfoService.toDiscordAllUserInfoFind(criteria, searchForUserIp));

		//then
		assertEquals(NOT_EXIST_CONNECTED_USER.getMessage(), connectedUserException.getMessage());
	}

	@Test
	@Order(16)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ์ƒ์„ธ ์กฐํšŒ ํ…Œ์ŠคํŠธ")
	void toDiscordDetailConnectedUserInfoFind() {
		//given
		System.out.println(
			"Service Logic ์ €์žฅ ์ƒํƒœ ์—ฌ๋ถ€ ํ™•์ธ : " + connectedUserInfoService.save(userRequestTotalInfoSaveRequestDto));

		UserInfoDetailSearchRequestDto userInfoDetailSearchRequestDto = new UserInfoDetailSearchRequestDto();
		userInfoDetailSearchRequestDto.setConnectedUserRequestInfoID("1");
		userInfoDetailSearchRequestDto.setCrewGrade(TEAM_LEADER);

		//when
		DefaultResponse<UserInfoDetailResponseDto> responseInfo = connectedUserInfoService.toDiscordDetailConnectedUserInfoFind(
			userInfoDetailSearchRequestDto);

		//then
		assertThat(responseInfo.getStatusCode()).isEqualTo(200);
		assertThat(responseInfo.getMessage()).isEqualTo("์„ฑ๊ณต");
	}

	@Test
	@Order(17)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ์ƒ์„ธ ์กฐํšŒ ์‹œ ๊ถŒํ•œ ์—†๋Š” ํฌ๋ฃจ๊ฐ€ ์กฐํšŒ ์š”์ฒญ ์‹œ ๋ฌธ์ œ ํ…Œ์ŠคํŠธ")
	void toDiscordDetailConnectedUserInfoUnAuthorizedFind() {
		//given
		UserInfoDetailSearchRequestDto userInfoDetailSearchRequestDto = new UserInfoDetailSearchRequestDto();
		userInfoDetailSearchRequestDto.setConnectedUserRequestInfoID("1");
		userInfoDetailSearchRequestDto.setCrewGrade(GENERAL_CREW);

		//when
		ConnectedUserException connectedUserException = Assertions.assertThrows(ConnectedUserException.class,
			() -> connectedUserInfoService.toDiscordDetailConnectedUserInfoFind(userInfoDetailSearchRequestDto));

		//then
		assertEquals(NO_AUTHORIZATION.getMessage(), connectedUserException.getMessage());
	}

	@Test
	@Order(18)
	@DisplayName("์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ ์š”์ฒญ ์ •๋ณด ์ƒ์„ธ ์กฐํšŒ ์‹œ ๊ฒฐ๊ณผ ๊ฐ’ ์—†์„ ๋•Œ, ๋ฌธ์ œ ํ…Œ์ŠคํŠธ")
	void toDiscordDetailConnectedUserInfoNotFind() {
		//given
		UserInfoDetailSearchRequestDto userInfoDetailSearchRequestDto = new UserInfoDetailSearchRequestDto();
		userInfoDetailSearchRequestDto.setConnectedUserRequestInfoID("99999999");
		userInfoDetailSearchRequestDto.setCrewGrade(TEAM_LEADER);

		//when
		ConnectedUserException connectedUserException = Assertions.assertThrows(ConnectedUserException.class,
			() -> connectedUserInfoService.toDiscordDetailConnectedUserInfoFind(userInfoDetailSearchRequestDto));

		//then
		assertEquals(NOT_EXIST_CONNECTED_USER.getMessage(), connectedUserException.getMessage());
	}

	/**
	 * <b>์ด์šฉ์ž ์ •๋ณด ์ €์žฅ ๊ฐ„ ๊ด€๊ณ„ ํ…Œ์ด๋ธ” ์ •๋ณด ์ €์žฅ ์‹œ ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ฌ ์š”์ธ์„ ๋งŒ๋“ค Method</b>
	 * @param errorCause ๊ฐ Test Case์—์„œ ์ƒํ™ฉ๋ณ„๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ด์šฉํ•  Keyword
	 * @return ์ด์šฉ์ž ์ •๋ณด ์ €์žฅ์„ ์œ„ํ•œ ๋ฌธ์ œ ์žˆ๋Š” ์š”์ฒญ DTO
	 */
	private UserRequestTotalInfoSaveRequestDto createErrorStatusDto(String errorCause) {
		switch (errorCause) {
			case "serverInfo":
				return UserRequestTotalInfoSaveRequestDto.builder()
					.serverInfo(null)
					.dataCreatedDateTimeRequestDTO(dataCreatedDateTimeRequestDto)
					.connectedUserInfoSaveRequestDTO(connectedUserInfoSaveRequestDto)
					.connectedUserRequestInfoSaveRequestDTO(connectedUserRequestInfoSaveRequestDto)
					.build();
			case "occurrenceDateTime":
				return UserRequestTotalInfoSaveRequestDto.builder()
					.serverInfo(serverInfo)
					.dataCreatedDateTimeRequestDTO(null)
					.connectedUserInfoSaveRequestDTO(connectedUserInfoSaveRequestDto)
					.connectedUserRequestInfoSaveRequestDTO(connectedUserRequestInfoSaveRequestDto)
					.build();
			case "userInfo":
				return UserRequestTotalInfoSaveRequestDto.builder()
					.serverInfo(serverInfo)
					.dataCreatedDateTimeRequestDTO(dataCreatedDateTimeRequestDto)
					.connectedUserInfoSaveRequestDTO(null)
					.connectedUserRequestInfoSaveRequestDTO(connectedUserRequestInfoSaveRequestDto)
					.build();
			default:
				return UserRequestTotalInfoSaveRequestDto.builder()
					.serverInfo(serverInfo)
					.dataCreatedDateTimeRequestDTO(dataCreatedDateTimeRequestDto)
					.connectedUserInfoSaveRequestDTO(connectedUserInfoSaveRequestDto)
					.connectedUserRequestInfoSaveRequestDTO(null)
					.build();
		}
	}

	/**
	 * <b>Test์— ์‚ฌ์šฉ๋  DTO, VO๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method</b>
	 * @return ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด์™€ ์„œ๋ฒ„ ์ •๋ณด ๋“ฑ์„ ํฌํ•จํ•œ ์š”์ฒญ DTO ๊ฐ์ฒด
	 */
	private UserRequestTotalInfoSaveRequestDto initializedMockModels() {
		this.dataCreatedDateTimeVo = initializedCreateDateTime();
		this.serverInfoVo = initializedServerInfo();
		this.userInfoVO = initializedConnectedUserInfo();
		this.userRequestInfoVo = initializedConnectedUserRequestInfo();

		return UserRequestTotalInfoSaveRequestDto.builder()
			.serverInfo(serverInfo)
			.dataCreatedDateTimeRequestDTO(dataCreatedDateTimeRequestDto)
			.connectedUserInfoSaveRequestDTO(connectedUserInfoSaveRequestDto)
			.connectedUserRequestInfoSaveRequestDTO(connectedUserRequestInfoSaveRequestDto)
			.build();
	}

	/**
	 * <b>์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method</b>
	 * @return ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด Value Object
	 */
	private UserRequestInfoVo initializedConnectedUserRequestInfo() {
		this.connectedUserRequestInfoSaveRequestDto = ConnectedUserRequestInfoSaveRequestDto.builder()
			.internalServerID(1L)
			.dataCreatedDateTimeID(1L)
			.connectedUserID(1L)
			.userCookiesArray(null)
			.userCookies("๋‚ด์šฉ ์—†์Œ")
			.requestHeader("\"sec-fetch-mode\" : \"cors\",\n")
			.requestParameter("\"perPageNum\" : \"10\",\n" + "\"displayPageNum\" : \"10\",\n"
				+ "\"inputSearchType\" : \"USER_CONNECTED_DATE\",\n" + "\"endDate\" : \"2023-06-01\",\n"
				+ "\"page\" : \"1\",\n" + "\"startDate\" : \"2023-01-01\"")
			.requestBody("")
			.build();

		return UserRequestInfoVo.toVo(connectedUserRequestInfoSaveRequestDto);
	}

	/**
	 * <b>์ด์šฉ์ž ์ ‘์† ์ •๋ณด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method</b>
	 * @return ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด๋ฅผ ๋‹ด์€ Value Object
	 */
	private ConnectedUserInfoVo initializedConnectedUserInfo() {
		this.connectedUserInfoSaveRequestDto = ConnectedUserInfoSaveRequestDto.builder()
			.internalServerID(1L)
			.dataCreatedDateTimeID(1L)
			.userIP("127.0.0.1")
			.userLocation(
				"\"reason\" : \"ReservedIPAddress\",\n" + "\"reserved\" : \"true\",\n"
					+ "\"ip\" : \"127.0.0.1\",\n"
					+ "\"error\" : \"true\",\n" + "\"version\" : \"IPv4\"\n")
			.userEnvironment("\"Mozilla/5.0\"")
			.build();

		return ConnectedUserInfoVo.toVO(connectedUserInfoSaveRequestDto);
	}

	/**
	 * <b>์ด์šฉ์ž ์ ‘์† ๋ฐ ์š”์ฒญ์ผ์‹œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method</b>
	 * @return ์ ‘์† ๋ฐ ์š”์ฒญ ์ผ์‹œ๋ฅผ ๋‹ด์€ Value Object
	 */
	private DataCreatedDateTimeVo initializedCreateDateTime() {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String[] splitNowDateTime = simpleDateFormat.format(new Date(System.currentTimeMillis())).split(" ");

		this.dataCreatedDateTimeRequestDto = DataCreatedDateTimeRequestDto.builder()
			.createdDate(splitNowDateTime[0])
			.createdTime(splitNowDateTime[1])
			.build();

		return DataCreatedDateTimeVo.toVO(dataCreatedDateTimeRequestDto);
	}

	/**
	 * <b>๋‚ด๋ถ€ ์„œ๋ฒ„ ์ •๋ณด ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method</b>
	 * @return ๋‚ด๋ถ€ ์„œ๋ฒ„ ์ •๋ณด ๋‹ด์€ Value Object
	 */
	private ServerInfoVo initializedServerInfo() {
		this.serverInfo = ServerInfo.builder()
			.serverName(GiggalPeopleServerNames.GIGGAL_TOTAL_BACK_OFFICE.getDescription())
			.vmInfo("OpenJDK 64-Bit")
			.osInfo("Mac OS")
			.serverIP("192.168.20.254")
			.serverEnvironment("dev")
			.build();

		this.serverInfoSaveRequestDto = ServerInfoSaveRequestDto.builder()
			.serverName(serverInfo.getServerName())
			.serverVmInfo(serverInfo.getVmInfo())
			.serverOsInfo(serverInfo.getOsInfo())
			.serverIP(serverInfo.getServerIP())
			.serverEnvironment(serverInfo.getServerEnvironment())
			.build();

		return ServerInfoVo.toVo(serverInfoSaveRequestDto);
	}

	/**
	 * <b>์ƒ์„ธ ์กฐํšŒ ์š”์ฒญ DTO ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method</b>
	 */
	private void initializedMockDetailRequestDto() {
		this.userInfoDetailSearchRequestDto = new UserInfoDetailSearchRequestDto();
		this.userInfoDetailSearchRequestDto.setConnectedUserRequestInfoID("1");
		this.userInfoDetailSearchRequestDto.setCrewGrade(TEAM_LEADER);
	}

	/**
	 * <b>๊ฐ€์งœ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method</b>
	 * @param splitNowDateTime ์ ‘์† ์ผ์‹œ๋ฅผ ๊ณต๋ฐฑ ๊ธฐ์ค€์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋‹ด๊ธด ๋ฐฐ์—ด
	 */
	private void initializedMockUserInfo(String[] splitNowDateTime) {
		this.userInfoList = new ArrayList<>();
		IntStream.rangeClosed(1, 11).forEach(count -> {
			this.userInfoList.add(UserInfoListResponseDto.builder()
				.connectedUserRequestInfoID((long)count)
				.connectedDateTime(splitNowDateTime[0] + " " + splitNowDateTime[1])
				.serverName(GiggalPeopleServerNames.GIGGAL_TOTAL_BACK_OFFICE.getDescription())
				.userIP("127.0.0." + count)
				.build());
		});
	}

	/**
	 * <b>Paging ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ Criteria ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ Method</b>
	 */
	private void initializedMockCriteria() {
		this.criteria = new Criteria();
		this.criteria.setPage(1);
		this.criteria.setPerPageNum(10);
		this.criteria.setPageMoveButtonNum(10);
	}

	/**
	 * <b>์ด์šฉ์ž IP ์ฃผ์†Œ๋ฅผ ํ†ตํ•ด ๊ฒ€์ƒ‰ํ•˜๊ณ ์ž ํ•  ๋•Œ, ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ ๊ฐ์ฒด DTO</b>
	 */
	private void initializedMockSearchUserIpRequestDto() {
		this.searchForUserIp = new UserInfoSearchDto();
		this.searchForUserIp.setInputSearchType(UserInfoSearchType.USER_IP);
		this.searchForUserIp.setSearchWord("127.0.0.1");
	}

	/**
	 * <b>๋‚ด๋ถ€ ์„œ๋ฒ„ IP ์ฃผ์†Œ๋ฅผ ํ†ตํ•ด ๊ฒ€์ƒ‰ํ•˜๊ณ ์ž ํ•  ๋•Œ, ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ ๊ฐ์ฒด DTO</b>
	 */
	private void initializedMockSearchServerIpRequestDto() {
		this.searchForServerIp = new UserInfoSearchDto();
		this.searchForServerIp.setInputSearchType(UserInfoSearchType.SERVER_IP);
		this.searchForServerIp.setSearchWord("192.168.20.254");
	}

	/**
	 * <b>๋‚ด๋ถ€ ์„œ๋ฒ„ ์ด๋ฆ„์„ ํ†ตํ•ด ๊ฒ€์ƒ‰ํ•˜๊ณ ์ž ํ•  ๋•Œ, ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ ๊ฐ์ฒด DTO</b>
	 */
	private void initializedMockSearchServerNameRequestDto() {
		this.searchForServerName = new UserInfoSearchDto();
		this.searchForServerName.setInputSearchType(UserInfoSearchType.SERVER_NAME);
		this.searchForServerName.setSearchWord("ํ†ตํ•ฉ๊ด€๋ฆฌ์„œ๋ฒ„");
	}

	/**
	 * <b>์ด์šฉ์ž ์ ‘์†์ผ ํ†ตํ•ด ๊ฒ€์ƒ‰ํ•˜๊ณ ์ž ํ•  ๋•Œ, ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ ๊ฐ์ฒด DTO</b>
	 */
	private void initializedMockSearchUserConnectedDateRequestDto(String searchDate) {
		this.searchForUserConnectedDate = new UserInfoSearchDto();
		this.searchForUserConnectedDate.setInputSearchType(UserInfoSearchType.USER_CONNECTED_DATE);
		this.searchForUserConnectedDate.setDate(searchDate);
	}

	/**
	 * <b>์ด์šฉ์ž ์ ‘์†์ผ ๋ฒ”์œ„ ๊ฒ€์ƒ‰ํ•˜๊ณ ์ž ํ•  ๋•Œ, ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ ๊ฐ์ฒด DTO</b>
	 */
	private void initializedMockSearchUserConnectedDateRangeRequestDto(String nowDate) {
		this.searchForUserConnectedDateRange = new UserInfoSearchDto();
		this.searchForUserConnectedDateRange.setInputSearchType(UserInfoSearchType.USER_CONNECTED_DATE);
		this.searchForUserConnectedDateRange.setStartDate("2023-01-01");
		this.searchForUserConnectedDateRange.setEndDate(nowDate);
	}

	/**
	 * <b>์ด์šฉ์ž ์ ‘์† ์ˆœ์„œ ๋ฒˆํ˜ธ ๊ฒ€์ƒ‰ํ•˜๊ณ ์ž ํ•  ๋•Œ, ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ ๊ฐ์ฒด DTO</b>
	 */
	private void initializedMockSearchUserIdRequestDto() {
		this.searchForUserId = new UserInfoSearchDto();
		this.searchForUserId.setInputSearchType(CONNECTED_USER_REQUEST_ID);
		this.searchForUserId.setSearchWord("1");
	}
}


์ „์ฒด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์œ„์™€ ๊ฐ™์•„์š”.

์ตœ์ดˆ ํด๋ž˜์Šค ์ด๋ฆ„ ์œ„์— ์‚ฌ์šฉํ•œ Annotation ๋ถ€ํ„ฐ ์•Œ์•„๋ณผ๊ฒŒ์š”.

โˆ™ @TestMethodOrder(MethodOrderer.OrderAnnotaion.class): ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์€ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ ์ˆœ์„œ ์ง€์ •์„ ์œ„ํ•ด ์‚ฌ์šฉ.
    - MethodOrderer.OrderAnnotaion.class๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด @Order๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ ์ˆœ์„œ ์ง€์ • ๊ฐ€๋Šฅ.

โˆ™ @ExtendWith(SpringExtension.class): JUnit5์—์„œ ์Šคํ”„๋ง ํ…Œ์ŠคํŠธ ์ปจํ…์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ์™€ JUnit 5๋ฅผ ํ†ตํ•ฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ
    ์ˆ˜ํ–‰ํ•  ๋•Œ ๋ช…์‹œ. ์Šคํ”„๋ง ๋ถ€ํŠธ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, SpringExtension ํด๋ž˜์Šค๊ฐ€ JUnit 5์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ ๋˜์–ด ์Šคํ”„๋ง ํ…Œ์ŠคํŠธ ์ปจํ…์ŠคํŠธ
     ํ”„๋ ˆ์ž„์›Œํฌ์™€์˜ ํ†ตํ•ฉ ์ง€์›.

โˆ™ @SpringBootTest: ์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ๋ช…์‹œ. ์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ๋ฅผ ๋กœ๋“œํ•˜์—ฌ ํ…Œ์ŠคํŠธ์— ์‚ฌ
    ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  Bean์„ ๋กœ๋“œํ•˜์ง€๋งŒ, ํŠน์ • ๊ตฌ์„ฑ ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•˜์—ฌ ๋กœ๋“œํ•  ์ˆ˜๋„ ์žˆ์Œ.
    ์ฆ‰, ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋กœ์ปฌ ์œ„์— ์˜ฌ๋ ค Listening Port ์ฃผ์†Œ๊ฐ€ Listening ๋˜์–ด ์ง€๊ณ , ์‹ค์ œ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์™€ ์—ฐ๊ฒฐ์ด ๋ถ™์–ด์ง€๋Š” ์ƒํƒœ์—์„œ
    ์ง„ํ–‰๋˜๋Š” Live ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด ๋ช…์‹œ.

์ฆ‰ ์œ„์˜ ์–ด๋…ธํ…Œ์ด์…˜๋“ค์€ ์Šคํ”„๋ง ํ…Œ์ŠคํŠธ ์ปจํ…์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ์™€ JUnit 5๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์„ค์ •์œผ๋กœ @TestMethodOrder๋ฅผ ํ†ตํ•ด ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์ง€์ •ํ•˜๊ณ , @ExtendWith๋ฅผ ํ†ตํ•ด
์Šคํ”„๋ง ํ…Œ์ŠคํŠธ ์ปจํ…์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ์™€ JUnit 5๋ฅผ ํ†ตํ•ฉํ•˜๋ฉฐ,
@SpringBootTest๋กœ ์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปจํ…์ŠคํŠธ๋ฅผ ๋กœ๋“œํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ ๊ฒƒ์ด์—์š”.

 

ConnectedUserInfoServiceImplTest 120 ~ 125๋ฒˆ์งธ ์ค„


์œ„ ์ฝ”๋“œ๋Š” @BeforeEach๋ฅผ ํ†ตํ•ด ๊ฐ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค ๋‚ด์˜ ๊ฐ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ์ „ ์ดˆ๊ธฐํ™” ์ž‘์—…์ด๋‚˜, ์„ค์ • ์ž‘์—…์ด ํ•„์š”ํ•  ๋•Œ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ต๋‹ˆ๋‹ค.

ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ๋ฉ”์†Œ๋“œ๋Š” ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „ ๋งค๋ฒˆ ํ˜ธ์ถœ๋˜๊ฒŒ ๋˜์š”. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋œ ๋ฉ”์†Œ๋“œ๋Š” ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ๋“ค ๊ฐ„์˜ ๋…๋ฆฝ์„ฑ์„ ๋ณด์žฅํ•˜๋ฉด์„œ ๊ณตํ†ต์ ์ธ ์ค€๋น„ ์ž‘์—…์— ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•ด์š”.

์ฃผ๋‹ˆ๋Š” beforeTestSetup()์„ ํ†ตํ•ด initalizedMockModles()๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ๋ฐ˜ํ™˜๋œ ๊ฐ’์„ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ userRequestTotalInfoSaveRequestDto์— ๋‹ด์•„ ์ฃผ์—ˆ์–ด์š”.

this๋Š” ํ˜„์žฌ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฅดํ‚ค๋Š” ํ‚ค์›Œ๋“œ๋กœ ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์™€ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ด์š”.
์ฃผ๋‹ˆ๋Š” ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ์œ„์™€ ๊ฐ™์ด this ํ‚ค์›Œ๋“œ๋ฅผ ์จ ์ฃผ์—ˆ๋Š”๋ฐ, ๋งŒ์•ฝ ํด๋ž˜์Šค ๋‚ด์˜ ๋ฉ”์†Œ๋“œ๋‚˜, ์ƒ์„ฑ์ž์—์„œ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์™€ ์ง€์—ญ ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์ด ๊ฐ™์•„ ์ถฉ๋Œํ•  ๊ฒฝ์šฐ this๋ฅผ ๋ถ™์—ฌ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์ž„์„ ๋ช…์‹œํ•˜์—ฌ ๊ตฌ๋ถ„ํ•ด ์ค„ ์ˆ˜ ์žˆ์–ด์š”.

ConnectedUserInfoServiceImplTest 599 ~ 615๋ฒˆ์งธ ์ค„


ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋Š” ๊ฐ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์—์„œ ์‚ฌ์šฉ๋  DTO์™€ VO๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ์—์š”.

604 ~ 607๋ฒˆ์งธ ์ค„๊นŒ์ง€ ๊ฐ๊ฐ์˜ VO ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๊ณ , ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ์ฒด๋ฅผ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋กœ ์ €์žฅํ•ด ์ฃผ๊ณ  ์žˆ์–ด์š”.

ConnectedUserInfoServiceImplTest initializedCreateDateTime()


์œ„ ๋ฉ”์†Œ๋“œ๋Š” yyyy-MM-dd ํ˜•์‹์˜ ๋‚ ์งœ๊ฐ’ (์ด์šฉ์ž ์š”์ฒญ ๋‚ ์งœ๊ฐ’)๊ณผ HH:mm:ss ํ˜•์‹์˜ ์‹œ๊ฐ„๊ฐ’ (์ด์šฉ์ž ์š”์ฒญ ์‹œ๊ฐ„๊ฐ’)์„ ๊ณต๋ฐฑ์„ ๊ธฐ์ค€์œผ๋กœ ๋ถ„๋ฆฌํ•œ ๋’ค splitNowDateTime ๋ฌธ์ž์—ด ๋ฐฐ์—ด ์ฒซ๋ฒˆ์งธ์— ๋‚ ์งœ๊ฐ’์„ ๋„ฃ๊ณ , ๋‘๋ฒˆ์งธ์— ์‹œ๊ฐ„๊ฐ’์„ ๋„ฃ์–ด์ค€ ๋’ค ์ด๋ฅผ ๋นŒ๋” ํŒจํ„ด์„ ์ด์šฉํ•˜์—ฌ DataCreatedDateTimeRequestDto ๊ฐ์ฒด์— ๋„ฃ์–ด์ฃผ๊ณ , ํ•ด๋‹น ๊ฐ’์„ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ dataCreatedDateTimeRequestDto์— ๋„ฃ์–ด์ค€ ๋’ค toVO()๋ฅผ ์ด์šฉํ•˜์—ฌ DTO ๊ฐ’์„ VO ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.


ConnectedUserInfoServiceImplTest initializedServerInfo()


์œ„ ๋ฉ”์†Œ๋“œ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์„œ๋ฒ„ ์ •๋ณด๋ฅผ ํ•˜๋“œ ์ฝ”๋”ฉํ•˜์—ฌ ๋„ฃ์–ด ์ฃผ๋Š” ๋ถ€๋ถ„์ด์—์š”.

์ด๋ ‡๊ฒŒ ํ•ด์„œ 686~692๋ฒˆ์งธ ์ค„์„ ํ†ตํ•ด DTO ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์— ๋„ฃ์–ด์ฃผ๊ณ , 694๋ฒˆ์งธ ์ค„์— toVo()๋ฅผ ํ†ตํ•ด DTO๋ฅผ VO๋กœ ๋ฐ”๊พธ์–ด ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.


ConnectedUserInfoServiceImplTest initializedConnectedUserInfo()


์œ„ ๋ฉ”์†Œ๋“œ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋‹ด๊ธฐ ์œ„ํ•œ ์ •๋ณด๋ฅผ ํ•˜๋“œ ์ฝ”๋”ฉํ•˜์—ฌ ๋„ฃ์–ด์ฃผ๋Š” ๋ถ€๋ถ„์ด์—์š”.

643 ~ 652๋ฒˆ์งธ ์ค„๊นŒ์ง€ DTO ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์— ๋„ฃ์–ด์ฃผ๊ณ , 653๋ฒˆ์งธ ์ค„์„ ํ†ตํ•ด VO๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.



ConnectedUserInfoServiceImplTest initializedConnectedUserRequestInfo()


์œ„ ๋ฉ”์†Œ๋“œ ์—ญ์‹œ 622 ~ 633๋ฒˆ์งธ ์ค„์„ ํ†ตํ•ด ํ•˜๋“œ ์ฝ”๋”ฉํ•˜์—ฌ ์ด์šฉ์ž์˜ ์š”์ฒญ ์ •๋ณด๋ฅผ DTO ๊ฐ์ฒด์— ๋„ฃ์–ด ๊ฐ์ฒดํ™” ํ•œ ๋’ค ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์— ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ , 635๋ฒˆ์งธ ์ค„์„ ํ†ตํ•ด VO๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.


ConnectedUserInfoServiceImplTest 599 ~ 615๋ฒˆ์งธ ์ค„

๋‹ค์‹œ ์ด ๊ณณ์œผ๋กœ ๋Œ์•„์™€์„œ 609 ~ 614๋ฒˆ์งธ ์ค„๊นŒ์ง€ ๋‚ด๋ถ€ ์„œ๋ฒ„ ์ •๋ณด๋ฅผ ๋‹ด์€ ๊ฐ์ฒด์™€ ์š”์ฒญ ์ผ์‹œ๋ฅผ ๋‹ด์€ DTO ๊ฐ์ฒด, ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋‹ด์€ DTO ๊ฐ์ฒด, ์š”์ฒญ ์ด์šฉ์ž์˜ ์š”์ฒญ ์ •๋ณด๋ฅผ ๋‹ด์€ DTO๋ฅผ UserRequestTotalInfoSaveReqeuestDto ๊ฐ์ฒด์— ๋„ฃ์–ด ์ตœ์ข…์ ์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜์˜€์–ด์š”.



ConnectedUserInfoServiceImplTest 120 ~ 125๋ฒˆ์งธ ์ค„


๊ทธ๋Ÿฐ ๋’ค 124๋ฒˆ์งธ ์ค„์— initializedMockSearchRequestDto()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฒ€์ƒ‰ ํ…Œ์ŠคํŠธ ์‹œ ์‚ฌ์šฉํ•  ์ดˆ๊ธฐ๊ฐ’๋“ค์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ์ฃผ์—ˆ์–ด์š”.



์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์ €์žฅ ๊ด€๋ จ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด ๋ณผ๊ฒŒ์š”.

ConnectedUserInfoServiceImplTest save()


์œ„์˜ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ๋Š” JUnit 5๋ฅผ ์ด์šฉํ•˜์—ฌ connectedUserInfoService.save()๋ฅผ ํ…Œ์ŠคํŠธ ํ•˜๋Š” ์ฝ”๋“œ์—์š”.

โˆ™ @Test: ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๊ฐ€ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์ž„์„ ๋ช…์‹œํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ. ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ๋ฉ”์†Œ๋“œ๋“ค์€ ํ…Œ์ŠคํŠธ ์‹คํ–‰
    ๋Œ€์ƒ์œผ๋กœ ์ธ์‹.

โˆ™ @Order(0): ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์€ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ ์ˆœ์„œ ์ง€์ • ์‹œ ์‚ฌ์šฉ. JUnit 5์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์–ด๋…ธํ…Œ์ด์…˜ ์ค‘
    ํ•˜๋‚˜๋กœ, ์ •์ˆ˜ ๊ฐ’์„ ๊ฐ€์ง€๋ฉฐ, ๊ฐ’์ด ์ž‘์„์ˆ˜๋ก ๋จผ์ € ์‹คํ–‰๋œ๋‹ค.

โˆ™ @DisplayName(): ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์€ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ. JUnit 5์—์„œ๋Š” ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์˜
    ์ด๋ฆ„์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์—ฌ ๋” ์ฝ๊ธฐ ์‰ฝ๊ณ  ๋ช…ํ™•ํ•œ ์ด๋ฆ„์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š”๋‹ค. 

โˆ™// given, //when, //then: ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์˜ ํ…Œ์ŠคํŠธ ์ „๋žต ์ค‘ ํ•˜๋‚˜์ธ Given-When-Then์„ ํ‘œํ˜„ํ•œ ๊ฒƒ์œผ๋กœ ํ…Œ์ŠคํŠธ ์ „๋žต์€
  ์ฃผ์–ด์ง„ ์ƒํ™ฉ(Given)์—์„œ ํŠน์ • ๋™์ž‘(When)์„ ์‹คํ–‰ํ•˜๊ณ , ์˜ˆ์ƒํ•œ ๊ฒฐ๊ณผ (Then)์„ ๊ฒ€์ฆํ•˜๋Š” ํŒจํ„ด์„ ๋”ฐ๋ฅด๊ฒ ๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹œํ•˜๊ธฐ
  ์œ„ํ•ด ์‚ฌ์šฉ.

โˆ™ assertThat(): ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ๊ฒ€์ฆ ๋ฉ”์†Œ๋“œ๋กœ ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ. ์œ„ ํ…Œ์ŠคํŠธ์—์„œ๋Š”
   responseInfo ๊ฐ์ฒด์˜ getStatusCode()์™€ getMessage()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ๊ฐ’์„ ๊ฒ€์ฆ.

   - isEqualTo(): ๊ฒ€์ฆ ๋ฉ”์†Œ๋“œ ์ค‘ ํ•˜๋‚˜๋กœ ์˜ˆ์ƒํ•œ ๊ฐ’๊ณผ ๋งค๊ฐœ ๋ณ€์ˆ˜ ๊ฐ’์ด ์„œ๋กœ ๋™์ผํ•œ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ.
      assertThat(responseInfo.getStatusCode()).isEqualTo(201)๋Š” connectedUserInfoService.save()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ
      ์–ป์–ด์ง„ ๋ฐ˜ํ™˜๊ฐ’์ด ๋‹ด๊ธด responseInfo ๋ณ€์ˆ˜์— ๊ฐ’์— HTTP Status Code๊ฐ€ 201์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๋ช…์‹œ.

      assertThat(responseInfo.getMessage()).isEqualTo("์ƒ์„ฑ ์„ฑ๊ณต"): connectedUserInfoService.save()๋ฅผ
      ํ˜ธ์ถœํ•˜์—ฌ ์–ป์–ด์ง„ ๋ฐ˜ํ™˜๊ฐ’์ด ๋‹ด๊ธด responseInfo ๋ณ€์ˆ˜์— ๊ฐ’์— Message๊ฐ€ "์ƒ์„ฑ ์„ฑ๊ณต"๊ณผ ๊ฐ™์€์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๋ช…์‹œ.

 

ํ…Œ์ŠคํŠธ ์„ฑ๊ณต


์œ„์™€ ๊ฐ™์ด ํ…Œ์ŠคํŠธ ์„ฑ๊ณตํ•˜์˜€์–ด์š”.

ConnectedUserInfoServiceImplTest causedByServerInfoSaveFailure()


์œ„ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ๋Š” ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์ €์žฅ ์‹œ ๋‚ด๋ถ€ ์„œ๋ฒ„ ์ •๋ณด๊ฐ€ Null์ด์—ฌ์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ์„ ํ…Œ์ŠคํŠธ ํ•œ ๊ฒƒ์ด์—์š”.

166๋ฒˆ์งธ ์ค„์„ ๋ณด๋ฉด createErrorStatusDto()๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ๋ฌธ์ž์—ด serverInfo๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์–ด์š”.

ConnectedUserInfoServiceImplTest createErrorStatusDto()


๊ทธ ์ด์œ ๋Š” ์œ„์™€ ๊ฐ™์ด switch ๋ฌธ์—์„œ ๋ฌธ์ž์—ด์„ ๋ถ„๊ธฐํ•˜์—ฌ ์ฒ˜๋ฆฌ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

serverInfo ๋ฌธ์ž์—ด์ด ์ „๋‹ฌ๋˜๋ฉด 569 ~ 574๋ฒˆ์งธ ์ค„์„ ํ†ตํ•ด UserRequestTotalInfoSaveRequestDto ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ, ์ด ๋•Œ, ์„œ๋ฒ„ ์ •๋ณด์— Null ๊ฐ’์„ ๋„ฃ์–ด ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

 

ConnectedUserInfoServiceImplTest causedByServerInfoSaveFailure()


๋‹ค์‹œ ์œ„ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ๋กœ ๋Œ์•„๊ฐ€์„œ ๋ณด๋ฉด ์„œ๋ฒ„ ์ •๋ณด๊ฐ€ Null ๊ฐ’์ธ UserRequestTotalInfoSaveRequestDto ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ , ์•„๋ž˜ ๋‚ด์šฉ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•œ ๊ฒƒ์ด์—์š”.

โˆ™ assertThrows(ServerInfoException.class, () -> {}): ์ด ๋ฉ”์†Œ๋“œ๋Š” ํŠน์ • ์ฝ”๋“œ ๋ธ”๋ก (() -> {})์„ ์‹คํ–‰ํ•  ๋•Œ,
    ์ง€์ •ํ•œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ. ์œ„ ์ฝ”๋“œ์—์„œ๋Š” Custom Exception ServerInfoException์ด ํ„ฐ์ง€๋Š”์ง€
    ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ.


โˆ™ connectedUserInfoService.save(): ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์„œ๋ฒ„ ์ •๋ณด๊ฐ€ Null์ธ
    UserRequestTotalInfoSaveRequestErrorSatusDto๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด ๋“ฑ์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์‹œ๋„.

โˆ™ assertThrows ๋ฉ”์†Œ๋“œ์˜ ๋ฐ˜ํ™˜๊ฐ’: assertThrows๋Š” ์˜ˆ์™ธ๋ฅผ ๋ฐ›์•„์˜ค๊ฑฐ๋‚˜, ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์„ ๊ฒจ์šฐ ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•˜๊ฒŒ
   ๋˜๋Š”๋ฐ, ํ•ด๋‹น ์˜ˆ์™ธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ. ๋”ฐ๋ผ์„œ ServerInfoException์ด ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ์˜ˆ์™ธ ๊ฐ์ฒด
   serverInfoException ๋ณ€์ˆ˜์— Exception ๊ฐ์ฒด๋ฅผ ๋‹ด์•„ ์ €์žฅ. 

 

ํ…Œ์ŠคํŠธ ์„ฑ๊ณต


์ฃผ๋‹ˆ๋Š” ์œ„์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ด์šฉ์ž ์š”์ฒญ ์ ‘์† ์ผ์‹œ๊ฐ€ Null์ผ ๋•Œ, ์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด๊ฐ€ Null์ผ ๋•Œ, ์š”์ฒญ ์ด์šฉ์ž๊ฐ€ ์š”์ฒญํ•œ ์ •๋ณด๊ฐ€ Null ์ผ ๋•Œ, ๊ทธ๋ฆฌ๊ณ , UserRequestTotalInfoSaveRequestDto ๊ฐ์ฒด ์ž์ฒด๊ฐ€ Null ์ผ ๋•Œ๋ฅผ ๊ฐ๊ฐ ํ…Œ์ŠคํŠธ ํ•˜์—ฌ ์ฃผ์—ˆ๊ณ ,
๋ชจ๋‘ ์„ฑ๊ณต ํ•˜์˜€์–ด์š”.

DAO์™€ Mapper ํ…Œ์ŠคํŠธ ์—ญ์‹œ ์œ„์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด ์ฃผ์—ˆ์–ด์š”.

 

 

    ๐Ÿ”ฝ ํ…Œ์ŠคํŠธ

        ๐Ÿ“ฆ ์ •์ƒ ์ž‘๋™ ์—ฌ๋ถ€

ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด Swagger๋ฅผ ์ด์šฉํ•ด์„œ ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด ๋ชฉ๋ก์„ ์กฐํšŒํ•˜๋Š” API๋ฅผ ํ˜ธ์ถœํ•ด ๋ณผ๊ฒŒ์š”.

Target API Controller


๋Œ€์ƒ Controller 54๋ฒˆ์งธ์— ์ฃผ๋‹ˆ๊ฐ€ ๋งŒ๋“  ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ช…์‹œํ•ด ์ฃผ์—ˆ์–ด์š”.

 


์ง€๋‚œ ๊ธ€์—์„œ ๋งŒ๋“ค์—ˆ๋˜ API ๋™์ž‘ ์†Œ์š” ์‹œ๊ฐ„ ํ™•์ธ AOP๋กœ ์ธํ•ด 500 Error๊ฐ€ ๋ฐ˜ํ™˜๋œ๊ฑธ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

[Spring Boot][Total-Back-Office Project] AOP, Annotation์„ ์ด์šฉํ•œ API ๋™์ž‘ ์‹œ๊ฐ„ ์ธก์ •

์Šคํ”„๋ง ๋ถ€ํŠธ 3 ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ๋˜๊ธฐ : ์ž๋ฐ” ํŽธ COUPANG www.coupang.com "์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค." ๐Ÿ—‚ ๋ชฉ์ฐจ โœ… [Spring Boot][Total-Back-Office Pr

junyharang.tistory.com

 

[2023-07-17] [00:20:43.415] [WARN] 4506 [GlobalAPIExceptionAdvisor.java] handleTimeTraceException (117) : {}
com.giggalpeople.backoffice.common.exception.TimeTraceException: Method ๋™์ž‘ ์‹œ๊ฐ„ ๊ฒ€์ฆ ์™„๋ฃŒ : Warning!! ๊ธฐ์ค€์น˜๋ณด๋‹ค ๋™์ž‘ ์‹œ๊ฐ„์ด ๋†’๊ฒŒ ์ธก์ • ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค!!execution(DefaultResponse com.giggalpeople.backoffice.api.record.controller.ErrorRecordManagementController.logSave(TotalErrorRecordSaveRequestDto)) Method ๋™์ž‘ ์‹œ๊ฐ„์€ 606ms (0.606)์ดˆ ์ž…๋‹ˆ๋‹ค.
	at com.giggalpeople.backoffice.common.aop.TimeTraceAop.longTimeExceptionHandler(TimeTraceAop.java:130)
	at com.giggalpeople.backoffice.common.aop.TimeTraceAop.execute(TimeTraceAop.java:61)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
	at com.giggalpeople.backoffice.api.record.controller.ErrorRecordManagementController$$EnhancerBySpringCGLIB$$1c2d7a41.logSave(<generated>)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:696)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at com.giggalpeople.backoffice.common.filter.MDCFilter.doFilterInternal(MDCFilter.java:47)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at com.giggalpeople.backoffice.common.filter.ServletWrappingFilter.doFilterInternal(ServletWrappingFilter.java:26)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:829)

 

Server ์ •๋ณด

 

์ด์šฉ์ž ์š”์ฒญ ๋‚ ์งœ์™€ ์‹œ๊ฐ

 

์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด



์š”์ฒญ ์ด์šฉ์ž ์š”์ฒญ ์ •๋ณด


์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด์™€ ์š”์ฒญ ์ •๋ณด๋Š” ์œ„์™€ ๊ฐ™์ด ์•”ํ˜ธํ™” ๋˜์„œ ์ €์žฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

์š”์ฒญ ์ด์šฉ์ž ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ


API ์†Œ์š” ์‹œ๊ฐ„ ํ™•์ธ ๋ถ€๋ถ„์— Exception ์ฒ˜๋ฆฌ ๋ถ€๋ฅผ ์ฃผ์„ํ•˜๊ณ  ์œ„์™€ ๊ฐ™์ด ํ˜ธ์ถœํ•ด๋ณด๋ฉด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ๊ฐ’์ด ๋‚˜์˜ค๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.


์ด์šฉ์ž ์ƒ์„ธ ์กฐํšŒ


์ƒ์„ธ ์กฐํšŒ๋ฅผ ํ•˜๋ฉด ์œ„์™€ ๊ฐ™์ด ์ด์šฉ์ž ์ ‘์† ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

 

 

 

์Šคํ”„๋ง ๋ถ€ํŠธ 3 ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ๋˜๊ธฐ : ์ž๋ฐ” ํŽธ

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

 

 

 

 

728x90
๋ฐ˜์‘ํ˜•

'Back-End ์ž‘์—…์‹ค > Spring Framework' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Spring Boot][Total-Back-Office Project] Log Back์„ ์ด์šฉํ•œ Discord์— Exception ์ •๋ณด ๋ณด๋‚ด๊ธฐ ๋ฐ Data Base ์ €์žฅ feat.MyBatis & Test Code(JUnit 5) - โ‘ข ๋กœ๊ทธ ๋ฐ ์š”์ฒญ ์ด์šฉ์ž, ์š”์ฒญ ์ •๋ณด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ €์žฅ  (0) 2023.07.22
[Spring Boot][Total-Back-Office Project] Log Back์„ ์ด์šฉํ•œ Discord์— Exception ์ •๋ณด ๋ณด๋‚ด๊ธฐ ๋ฐ Data Base ์ €์žฅ feat.MyBatis & Test Code(JUnit 5) - โ‘ก ๋””์Šค์ฝ”๋“œ๋กœ ๋กœ๊ทธ ์ •๋ณด ๋ฐœ์†ก  (0) 2023.07.22
[Spring Boot][Total-Back-Office Project] AOP, Annotation์„ ์ด์šฉํ•œ API ๋™์ž‘ ์‹œ๊ฐ„ ์ธก์ •  (0) 2023.07.15
[Spring Boot] Discord Bot(๋””์Šค์ฝ”๋“œ ๋ด‡) ๋งŒ๋“ค๊ธฐ - ๋””์Šค์ฝ”๋“œ ๋ด‡์„ ์ด์šฉํ•˜์—ฌ API ํ˜ธ์ถœ  (0) 2023.03.17
[Spring Boot] Discord Bot(๋””์Šค์ฝ”๋“œ ๋ด‡) ๋งŒ๋“ค๊ธฐ - Spring Boot(์Šคํ”„๋ง ๋ถ€ํŠธ)๋ฅผ ์ด์šฉํ•œ ๊ฐ„๋‹จํ•œ API ๋งŒ๋“ค๊ธฐ feat.mybatis(๋งˆ์ด๋ฐ”ํ‹ฐ์Šค)  (0) 2023.03.17