├── .github
├── ISSUE_TEMPLATE
│ └── issue-template.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── seung_ci.yml
├── .gitignore
├── Dockerfile
├── Dockerfile-seung
├── HELP.md
├── README.md
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
├── main
├── java
│ └── com
│ │ └── hermes
│ │ └── ithermes
│ │ ├── AppConfig.java
│ │ ├── ItHermesApplication.java
│ │ ├── RedisConfig.java
│ │ ├── application
│ │ ├── AlarmService.java
│ │ ├── ContentsService.java
│ │ ├── CrawlingContentsLastUrlService.java
│ │ ├── ExternalAlarmClient.java
│ │ ├── JobService.java
│ │ ├── SubscribeService.java
│ │ ├── TelegramAlarm.java
│ │ ├── UpdateUserChatId.java
│ │ ├── UrlRecordService.java
│ │ ├── UserService.java
│ │ └── YoutubeAndNewsService.java
│ │ ├── domain
│ │ ├── entity
│ │ │ ├── AlarmSearch.java
│ │ │ ├── BaseEntity.java
│ │ │ ├── ContentsViewMapping.java
│ │ │ ├── CrawlingContents.java
│ │ │ ├── CrawlingContentsLastUrl.java
│ │ │ ├── Job.java
│ │ │ ├── JobSearch.java
│ │ │ ├── Keyword.java
│ │ │ ├── Subscribe.java
│ │ │ ├── UrlRecord.java
│ │ │ ├── User.java
│ │ │ ├── UserKeywordRegistry.java
│ │ │ ├── YoutubeAndNews.java
│ │ │ └── YoutubeAndNewsSearch.java
│ │ ├── exception
│ │ │ ├── EnumTypeFormatException.java
│ │ │ ├── ExpireTokenException.java
│ │ │ ├── JsonParseException.java
│ │ │ ├── NoAlarmDataException.java
│ │ │ ├── NoCrawlingDataException.java
│ │ │ ├── NotExistsRequestParamException.java
│ │ │ ├── SameIdException.java
│ │ │ ├── SameNicknameException.java
│ │ │ ├── SameUserException.java
│ │ │ ├── UnMatchedPasswordException.java
│ │ │ └── WrongIdOrPasswordException.java
│ │ ├── factory
│ │ │ ├── CrawlingContentsLastUrlFactory.java
│ │ │ ├── JobFactory.java
│ │ │ ├── KeywordFactory.java
│ │ │ ├── RedisFactory.java
│ │ │ ├── SubscribeFactory.java
│ │ │ ├── UrlRecordFactory.java
│ │ │ ├── UserFactory.java
│ │ │ ├── UserKeywordRegistryFactory.java
│ │ │ └── YoutubeAndNewsFactory.java
│ │ └── util
│ │ │ ├── ActiveType.java
│ │ │ ├── CategoryType.java
│ │ │ ├── ContentsProviderType.java
│ │ │ ├── ElasticSearchType.java
│ │ │ ├── GradeType.java
│ │ │ ├── JobType.java
│ │ │ ├── OrderType.java
│ │ │ └── RecommendKeywordType.java
│ │ ├── infrastructure
│ │ ├── CrawlingContentsLastUrlRepository.java
│ │ ├── JobRepository.java
│ │ ├── KeywordRepository.java
│ │ ├── SubscribeRepository.java
│ │ ├── UrlRecordRepository.java
│ │ ├── UserKeywordRegistryRepository.java
│ │ ├── UserRepository.java
│ │ ├── YoutubeAndNewsRepository.java
│ │ └── elastic
│ │ │ ├── AlarmSearchRepository.java
│ │ │ ├── JobSearchRepository.java
│ │ │ └── YoutubeAndNewsSearchRepository.java
│ │ └── presentation
│ │ ├── GlobalExceptionHandler.java
│ │ ├── aop
│ │ ├── ControllerLogAop.java
│ │ └── ServiceLogAop.java
│ │ ├── config
│ │ ├── AbstractElasticsearchConfiguration.java
│ │ └── ElasticSearchConfig.java
│ │ ├── controller
│ │ ├── AlarmController.java
│ │ ├── ContentsController.java
│ │ ├── CrawlingContentsLastUrlController.java
│ │ ├── JobController.java
│ │ ├── SubscribeController.java
│ │ ├── UrlRecordController.java
│ │ ├── UserController.java
│ │ └── YoutubeAndNewsController.java
│ │ ├── dto
│ │ ├── CommonResponseDto.java
│ │ ├── alarm
│ │ │ ├── AlarmDtoInterface.java
│ │ │ ├── JobAlarmDto.java
│ │ │ └── YoutubeAndNewsAlarmDto.java
│ │ ├── contents
│ │ │ ├── CategoryCountDto.java
│ │ │ ├── ContentsDto.java
│ │ │ ├── ContentsDtoInterface.java
│ │ │ ├── MainPageContentsDto.java
│ │ │ └── SearchContentsDto.java
│ │ ├── crawlingcontentslasttitle
│ │ │ └── CrawlingContentsLastUrlFindAllResponseDto.java
│ │ ├── error
│ │ │ ├── EntryPointErrorResponse.java
│ │ │ └── UserErrorDto.java
│ │ ├── job
│ │ │ ├── JobCrawlingDto.java
│ │ │ └── JobInsertRequestDto.java
│ │ ├── subscribe
│ │ │ ├── SubscribeContentsDto.java
│ │ │ ├── SubscribeFindSubscribeRequestDto.java
│ │ │ ├── SubscribeFindSubscribeResponseDto.java
│ │ │ └── SubscribePutSubscribeRequestDto.java
│ │ ├── urlrecord
│ │ │ └── UrlRecordPutViewCountRequestDto.java
│ │ ├── user
│ │ │ ├── UserCheckRefreshTokenResponseDto.java
│ │ │ ├── UserCreateUserRequestDto.java
│ │ │ ├── UserDeleteUserRequestDto.java
│ │ │ ├── UserDuplicateIdRequestDto.java
│ │ │ ├── UserDuplicateNicknameRequestDto.java
│ │ │ ├── UserFindMyDataRequestDto.java
│ │ │ ├── UserFindMyDataResponseDto.java
│ │ │ ├── UserFindUserListResponseDto.java
│ │ │ ├── UserLoginRequestDto.java
│ │ │ ├── UserLoginResponseDto.java
│ │ │ └── UserUpdateNicknameRequestDto.java
│ │ └── youtubeandnews
│ │ │ ├── YoutubeAndNewsCrawlingDto.java
│ │ │ └── YoutubeAndNewsInsertDto.java
│ │ └── security
│ │ ├── CustomAccessDeniedHandler.java
│ │ ├── CustomAuthenticationEntryPoint.java
│ │ ├── JwtFilter.java
│ │ ├── JwtUtil.java
│ │ ├── SecurityConfiguration.java
│ │ └── SecurityErrorCode.java
└── resources
│ ├── application-eun.yml
│ ├── application-local.yml
│ ├── application-seung.yml
│ ├── application.yml
│ └── ehcache.xml
└── test
├── java
└── com
│ └── hermes
│ └── ithermes
│ ├── application
│ ├── ContentsServiceTest.java
│ ├── SubscribeServiceTest.java
│ └── UserServiceTest.java
│ └── presentation
│ └── controller
│ ├── SubscribeControllerTest.java
│ └── UserControllerTest.java
└── resources
└── application.yml
/.github/ISSUE_TEMPLATE/issue-template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Issue Template
3 | about: "\U0001F4D6 이슈 템플릿입니다."
4 | title: 'Prefix: 이슈 타이틀'
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## ❗About
11 |
12 | *
13 |
14 |
15 | ## 📝 To do
16 |
17 | - [ ]
18 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## 📌 관련 이슈
2 | - Resolved #
3 |
4 | ## ✔️ 작업 내용
5 | -
6 |
--------------------------------------------------------------------------------
/.github/workflows/seung_ci.yml:
--------------------------------------------------------------------------------
1 | # This workflow uses actions that are not certified by GitHub.
2 | # They are provided by a third-party and are governed by
3 | # separate terms of service, privacy policy, and support
4 | # documentation.
5 | # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
6 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
7 |
8 | name: Java CI with Gradle
9 |
10 | on:
11 | push:
12 | branches: "**"
13 | pull_request:
14 | branches: [ "main" ]
15 |
16 | jobs:
17 | build:
18 |
19 | runs-on: ubuntu-latest
20 |
21 | steps:
22 | - uses: actions/checkout@v3
23 | - name: Set up JDK 17
24 | uses: actions/setup-java@v3
25 | with:
26 | java-version: '17'
27 | distribution: 'temurin'
28 | - name: Validate Gradle wrapper
29 | uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
30 | - name: Build with Gradle
31 | uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
32 | with:
33 | arguments: build
34 |
35 | - name: Gradlew에 권한 부여
36 | run: chmod +x gradlew
37 |
38 | - name: 스프링 부트 애플리케이션 코드, 테스트코드 확인
39 | run: ./gradlew clean build
40 |
41 | - name: 테스트 코드 실행
42 | run: ./gradlew --info test
43 |
44 | - name: 테스트 결과 시각화
45 | uses: EnricoMi/publish-unit-test-result-action@v1
46 | if: ${{ always() }}
47 | with:
48 | files: build/test-results/**/*.xml
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | .gradle
3 | build/
4 | !gradle/wrapper/gradle-wrapper.jar
5 | !**/src/main/**/build/
6 | !**/src/test/**/build/
7 |
8 | ### STS ###
9 | .apt_generated
10 | .classpath
11 | .factorypath
12 | .project
13 | .settings
14 | .springBeans
15 | .sts4-cache
16 | bin/
17 | !**/src/main/**/bin/
18 | !**/src/test/**/bin/
19 |
20 | ### IntelliJ IDEA ###
21 | .idea
22 | *.iws
23 | *.iml
24 | *.ipr
25 | out/
26 | !**/src/main/**/out/
27 | !**/src/test/**/out/
28 |
29 | ### NetBeans ###
30 | /nbproject/private/
31 | /nbbuild/
32 | /dist/
33 | /nbdist/
34 | /.nb-gradle/
35 |
36 | ### VS Code ###
37 | .vscode/
38 | src/main/resources/application.properties
39 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:17-jdk-alpine
2 | ARG JAR_FILE_PATH=./build/libs/it-hermes-0.0.1-SNAPSHOT.jar
3 | COPY ${JAR_FILE_PATH} app.jar
4 | ENTRYPOINT ["java","-Dspring.profiles.active=eun","-jar","/app.jar","-Dspring-boot.run.arguments=--datasource.password=${PASSWORD}, --jwt.secret=${JWT_KEY}, --telegram-key=${TELEGRAM_KEY}"]
5 |
--------------------------------------------------------------------------------
/Dockerfile-seung:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:17-jdk-alpine
2 | ARG JAR_FILE_PATH=./build/libs/it-hermes-0.0.1-SNAPSHOT.jar
3 | COPY ${JAR_FILE_PATH} app.jar
4 | ENTRYPOINT ["java","-Dspring.profiles.active=seung","-jar","/app.jar","-Dspring-boot.run.arguments=--datasource.username=${DATASOURCE_USERNAME}, --datasource.password=${DATASOURCE_PASSWORD}, --jwt.secret=${JWT_KEY}, --telegram-key=${TELEGRAM_KEY}"]
5 |
--------------------------------------------------------------------------------
/HELP.md:
--------------------------------------------------------------------------------
1 | # Read Me First
2 | The following was discovered as part of building this project:
3 |
4 | * The original package name 'com.hermes.it-hermes' is invalid and this project uses 'com.hermes.ithermes' instead.
5 |
6 | # Getting Started
7 |
8 | ### Reference Documentation
9 | For further reference, please consider the following sections:
10 |
11 | * [Official Gradle documentation](https://docs.gradle.org)
12 | * [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.0.0/gradle-plugin/reference/html/)
13 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.0.0/gradle-plugin/reference/html/#build-image)
14 | * [Spring Web](https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/#web)
15 | * [Spring Data JDBC](https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/#data.sql.jdbc)
16 | * [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/#using.devtools)
17 |
18 | ### Guides
19 | The following guides illustrate how to use some features concretely:
20 |
21 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
22 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
23 | * [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
24 | * [Using Spring Data JDBC](https://github.com/spring-projects/spring-data-examples/tree/master/jdbc/basics)
25 |
26 | ### Additional Links
27 | These additional references should also help you:
28 |
29 | * [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle)
30 |
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PROJECT IT-Hermes
2 |
3 | :paperclip: [서비스 링크](https://it-hermes.site)
4 |
5 | :paperclip: [IT-Hermes 크롤링서버 레포](https://github.com/f-lab-edu/IT-Hermes-Crawling)
6 | :paperclip: [IT-Hermes 배치서버 레포](https://github.com/f-lab-edu/IT-Hermes-Batch)
7 | :paperclip: [IT-Hermes 프론트 레포](https://github.com/f-lab-edu/IT-Hermes-Front)
8 |
9 |
10 | ## :thought_balloon: IT 관련 컨텐츠 알림 서비스
11 |
12 | ```프로젝트 기간: 2023.01.04 ~```
13 |
14 | > IT에 관심이 많은 유저에게 채용, 유투브, 뉴스 정보 등의 각종 IT 관련 컨텐츠를
15 | > 유저 맞춤형으로 자동 알림해주는 서비스
16 |
17 | - 20분 간격으로 배치서버를 통해 크롤링 서버를 호출해서 최신 IT 관련 컨텐츠를 수집
18 | - 30분 간격으로 배치서버를 통해 애플리케이션 서버를 호출해서 유저 구독 정보 알림 제공
19 | - 객체지향 원리와 디자인 패턴을 적용하여 코드 작성
20 | - 깃허브 액션으로 CI, 젠킨스로 CD 구축
21 | - 성능 부하 테스트를 통해 트랜잭션 처리 시간을 측정해서 처리 속도 개선
22 | - 스프링 시큐리티를 적용해서 인증 관련 로직을 반복을 최소화하면서 기능 구현
23 | - RabbitMQ를 이용해서 Batch 서버와 Crawling 서버 장애 대응
24 | - ElasticSearch를 이용해서 검색 트랜잭션 처리속도 개선 경험
25 |
26 |
27 |
28 | ## :page_facing_up: 기술 스택
29 |
30 |
31 | `spring boot 3.0`, `Java 17`
32 | `spring security`
33 | `Mysql 8.0`,`h2`,`Spring Data JPA`
34 | `Jenkins`, `Github action`
35 | `Docker`, `Docker hub`
36 | `Nodejs, NCP`
37 | `Feign Client`
38 | `Html`,`CSS`,`Javascript`
39 | `RabbitMQ`,`ElasticSearch`
40 | `Redis`,`EH Cache`
41 |
42 | ## :thought_balloon: 전체 구조
43 | 
44 |
45 |
46 |
47 |
48 |
49 | ## :page_facing_up: 트러블슈팅 개선
50 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | id 'org.springframework.boot' version '3.0.0'
4 | id 'io.spring.dependency-management' version '1.1.0'
5 | }
6 |
7 | group = 'com.hermes'
8 | version = '0.0.1-SNAPSHOT'
9 | sourceCompatibility = '17'
10 |
11 | configurations {
12 | compileOnly {
13 | extendsFrom annotationProcessor
14 | }
15 | }
16 |
17 | repositories {
18 | mavenCentral()
19 | }
20 |
21 | dependencies {
22 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
23 | implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
24 | implementation 'org.springframework.data:spring-data-elasticsearch:4.2.2'
25 | implementation 'org.springframework.boot:spring-boot-starter-web'
26 | compileOnly 'org.projectlombok:lombok'
27 | developmentOnly 'org.springframework.boot:spring-boot-devtools'
28 | annotationProcessor 'org.projectlombok:lombok'
29 | testImplementation 'org.springframework.boot:spring-boot-starter-test'
30 | runtimeOnly 'mysql:mysql-connector-java'
31 | implementation 'com.github.kshashov:spring-boot-starter-telegram:0.27'
32 | implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'
33 | implementation 'org.springframework.boot:spring-boot-starter-validation'
34 | implementation 'org.springframework.boot:spring-boot-starter-security'
35 | // https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt
36 | implementation 'io.jsonwebtoken:jjwt:0.9.1'
37 | // https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api
38 | implementation 'javax.xml.bind:jaxb-api:2.3.1'
39 | // https://mvnrepository.com/artifact/org.springframework.security/spring-security-test
40 | testImplementation 'org.springframework.security:spring-security-test'
41 | testImplementation 'com.h2database:h2'
42 | implementation 'org.springframework.boot:spring-boot-starter-cache'
43 | implementation 'net.sf.ehcache:ehcache:2.10.3'
44 | implementation 'org.springframework.boot:spring-boot-starter-data-redis'
45 | // https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310
46 | implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3'
47 | implementation 'com.fasterxml.jackson.core:jackson-databind'
48 |
49 |
50 | }
51 |
52 | tasks.named('test') {
53 | useJUnitPlatform()
54 | }
55 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/f-lab-edu/IT-Hermes-Server/49321940d116d1f838b22829e14edadeaea014d7/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if %ERRORLEVEL% equ 0 goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if %ERRORLEVEL% equ 0 goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | set EXIT_CODE=%ERRORLEVEL%
84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
86 | exit /b %EXIT_CODE%
87 |
88 | :mainEnd
89 | if "%OS%"=="Windows_NT" endlocal
90 |
91 | :omega
92 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'it-hermes'
2 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/AppConfig.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.hermes.ithermes.application.UpdateUserChatId;
5 | import com.hermes.ithermes.infrastructure.UserRepository;
6 | import com.pengrad.telegrambot.TelegramBot;
7 | import lombok.RequiredArgsConstructor;
8 | import org.springframework.beans.factory.annotation.Value;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.context.annotation.Configuration;
11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
12 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
13 |
14 | @EnableWebSecurity
15 | @Configuration
16 | @RequiredArgsConstructor
17 | public class AppConfig {
18 | @Value("${telegram-key}")
19 | private String telegramKey;
20 | private final UserRepository userRepository;
21 |
22 | @Bean
23 | public UpdateUserChatId updateUserChatId() {
24 | UpdateUserChatId updateUserChatId = new UpdateUserChatId(telegramBot());
25 | updateUserChatId.updateUserChatId(userRepository);
26 | return updateUserChatId;
27 | }
28 |
29 | @Bean
30 | public BCryptPasswordEncoder passwordEncoder() {
31 | return new BCryptPasswordEncoder();
32 | }
33 |
34 | @Bean
35 | public TelegramBot telegramBot() {
36 | return new TelegramBot(telegramKey);
37 | }
38 |
39 | @Bean
40 | public ObjectMapper objectMapper() {
41 | return new ObjectMapper();
42 | }
43 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/ItHermesApplication.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes;
2 |
3 | import com.hermes.ithermes.infrastructure.elastic.AlarmSearchRepository;
4 | import com.hermes.ithermes.infrastructure.elastic.JobSearchRepository;
5 | import com.hermes.ithermes.infrastructure.elastic.YoutubeAndNewsSearchRepository;
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.cache.annotation.EnableCaching;
9 | import org.springframework.context.annotation.ComponentScan;
10 | import org.springframework.context.annotation.FilterType;
11 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
12 |
13 | @EnableCaching
14 | @SpringBootApplication
15 | @EnableJpaRepositories(excludeFilters = @ComponentScan.Filter(
16 | type = FilterType.ASSIGNABLE_TYPE,
17 | classes = {JobSearchRepository.class, YoutubeAndNewsSearchRepository.class, AlarmSearchRepository.class}))
18 | public class ItHermesApplication {
19 | public static void main(String[] args) {
20 | SpringApplication.run(ItHermesApplication.class, args);
21 | }
22 | }
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/RedisConfig.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes;
2 |
3 | import com.hermes.ithermes.presentation.dto.contents.ContentsDtoInterface;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.context.annotation.Primary;
9 | import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
10 | import org.springframework.data.redis.core.RedisTemplate;
11 | import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
12 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
13 | import org.springframework.data.redis.serializer.StringRedisSerializer;
14 |
15 | @Configuration
16 | @Slf4j
17 | @EnableRedisRepositories
18 | public class RedisConfig {
19 | @Value("${spring.redis.ipAddress}")
20 | private String ipAddress;
21 |
22 | @Bean
23 | @Primary
24 | LettuceConnectionFactory lettuceConnectionFactory() {
25 | LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(ipAddress,6379);
26 | return lettuceConnectionFactory;
27 | }
28 |
29 | @Bean
30 | LettuceConnectionFactory cacheConnectionFactory() {
31 | LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(ipAddress,6380);
32 | return lettuceConnectionFactory;
33 | }
34 |
35 | @Bean
36 | public RedisTemplate, ?> redisTemplate() {
37 | RedisTemplate, ?> template = new RedisTemplate<>();
38 | template.setConnectionFactory(lettuceConnectionFactory());
39 | template.setKeySerializer(new StringRedisSerializer());
40 | template.setValueSerializer(new Jackson2JsonRedisSerializer<>(String.class));
41 | return template;
42 | }
43 |
44 | @Bean
45 | public RedisTemplate, ?> cacheRedisTemplate() {
46 | RedisTemplate template = new RedisTemplate<>();
47 | template.setConnectionFactory(cacheConnectionFactory());
48 | template.setKeySerializer(new StringRedisSerializer());
49 | template.setHashKeySerializer(new StringRedisSerializer());
50 | template.setHashValueSerializer(new StringRedisSerializer());
51 | template.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
52 | return template;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/AlarmService.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.domain.entity.*;
4 | import com.hermes.ithermes.domain.exception.NoAlarmDataException;
5 | import com.hermes.ithermes.domain.util.*;
6 | import com.hermes.ithermes.infrastructure.*;
7 | import com.hermes.ithermes.infrastructure.elastic.AlarmSearchRepository;
8 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
9 | import com.hermes.ithermes.presentation.dto.alarm.AlarmDtoInterface;
10 | import com.hermes.ithermes.presentation.dto.alarm.JobAlarmDto;
11 | import com.hermes.ithermes.presentation.dto.alarm.YoutubeAndNewsAlarmDto;
12 | import com.hermes.ithermes.presentation.dto.crawlingcontentslasttitle.CrawlingContentsLastUrlFindAllResponseDto;
13 | import lombok.RequiredArgsConstructor;
14 | import org.springframework.stereotype.Service;
15 | import org.springframework.transaction.annotation.Transactional;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 | import java.util.stream.Collectors;
20 | import java.util.stream.Stream;
21 |
22 | @Service
23 | @RequiredArgsConstructor
24 | @Transactional
25 | public class AlarmService {
26 |
27 | private final ExternalAlarmClient externalAlarmClient;
28 | private final UserRepository userRepository;
29 | private final SubscribeRepository subscribeRepository;
30 | private final YoutubeAndNewsRepository youtubeAndNewsRepository;
31 | private final JobRepository jobRepository;
32 | private final CrawlingContentsLastUrlRepository crawlingContentsLastUrlRepository;
33 | private final AlarmSearchRepository alarmSearchRepository;
34 |
35 | public CommonResponseDto sendSubscribeAlarm() {
36 | List youtubeAlarm = alarmSearchRepository.findByCategory(CategoryType.YOUTUBE)
37 | .orElseThrow(()-> new NoAlarmDataException());
38 | /*List newsAlarm = alarmSearchRepository.findByCategory(CategoryType.NEWS)
39 | .orElseThrow(()-> new NoAlarmDataException());*/
40 | /*List jobAlarm = alarmSearchRepository.findByCategory(CategoryType.JOB)
41 | .orElseThrow(()-> new NoAlarmDataException());*/
42 |
43 | for(int i = 0; i< youtubeAlarm.size(); i++){
44 | AlarmSearch alarmSearch = youtubeAlarm.get(i);
45 | externalAlarmClient.sendContentsMessage(getUserYoutubeAndNewsAlarmContents(alarmSearch),alarmSearch.getTelegramId());
46 | }
47 |
48 | /*
49 | for(int i = 0; i < newsAlarm.size(); i++){
50 | AlarmSearch alarmSearch = newsAlarm.get(i);
51 | externalAlarmClient.sendContentsMessage(getUserYoutubeAndNewsAlarmContents(alarmSearch),alarmSearch.getTelegramId());
52 | }*/
53 |
54 | return new CommonResponseDto();
55 | }
56 |
57 | public CommonResponseDto sendRecommendAlarm(){
58 | List userIdArr = userRepository.findUserId();
59 |
60 | /*
61 | for(int i = 0; i < userIdArr.size(); i++){
62 | externalAlarmClient.sendContentsMessage(getUserRecommendAlarmContents(userIdArr.get(i),CategoryType.YOUTUBE), userIdArr.get(i));
63 | externalAlarmClient.sendContentsMessage(getUserRecommendAlarmContents(userIdArr.get(i),CategoryType.NEWS), userIdArr.get(i));
64 | externalAlarmClient.sendJobMessage(getUserRecommendAlarmJobContents(userIdArr.get(i)),userIdArr.get(i));
65 | }*/
66 |
67 | return new CommonResponseDto();
68 | }
69 |
70 | public List getUserYoutubeAndNewsAlarmContents(AlarmSearch alarmSearch){
71 | List youtubeAndNewsAlarmList = new ArrayList<>();
72 |
73 | youtubeAndNewsAlarmList = youtubeAndNewsRepository.findYoutubeAndNewsByUrlGreater(crawlingContentsLastUrlRepository.findByContentsProvider(alarmSearch.getContentsProvider()).get().getLastUrl(),alarmSearch.getContentsProvider());
74 |
75 | return youtubeAndNewsAlarmList.stream()
76 | .map(m -> YoutubeAndNewsAlarmDto.convertEntityToDto(m))
77 | .collect(Collectors.toList());
78 | }
79 |
80 | public List getUserJobAlarmContents(long userIdx){
81 | List subscribe = subscribeRepository.findByUserIdAndCategoryAndIsActive(userIdx,CategoryType.JOB,ActiveType.ACTIVE);
82 | int userExperienceYear = userRepository.findUsersById(userIdx).getYearOfExperience();
83 | JobType jobType = userRepository.findUsersById(userIdx).getJob();
84 | List jobAlarmList = new ArrayList<>();
85 |
86 | for(int i = 0; i < subscribe.size(); i++){
87 | jobAlarmList = jobRepository.findJobByUrlGreater(crawlingContentsLastUrlRepository.findByContentsProvider(subscribe.get(i).getContentsProvider()).get().getLastUrl(),subscribe.get(i).getContentsProvider(),GradeType.checkGradleType(userExperienceYear),jobType);
88 | }
89 |
90 | return jobAlarmList.stream()
91 | .map(m -> JobAlarmDto.convertEntityToDto(m))
92 | .collect(Collectors.toList());
93 | }
94 |
95 | public List getUserRecommendAlarmContents(long userIdx, CategoryType type){
96 | List userRecommendKeywords = getRecommendKeywords(userIdx);
97 | List userContentsProviderList = subscribeRepository.findContentsProvider(ActiveType.ACTIVE, userIdx, type);
98 |
99 | List youtubeAndNewsSubscribeContents = userContentsProviderList.stream()
100 | .map(m -> youtubeAndNewsRepository.findYoutubeAndNewsByContentsProvider(m))
101 | .flatMap(List::stream)
102 | .collect(Collectors.toList());
103 |
104 | List youtubeAndNewsRecommendList = youtubeAndNewsSubscribeContents.stream()
105 | .filter(m -> m.isContainRecommendKeywords(userRecommendKeywords))
106 | .collect(Collectors.toList());
107 |
108 | return youtubeAndNewsRecommendList.stream()
109 | .distinct()
110 | .map(m -> YoutubeAndNewsAlarmDto.convertEntityToDto(m))
111 | .collect(Collectors.toList());
112 | }
113 |
114 | public List getUserRecommendAlarmJobContents(long userIdx){
115 | List userRecommendKeywords = getRecommendKeywords(userIdx);
116 | List userContentsProviderList = subscribeRepository.findContentsProvider(ActiveType.ACTIVE, userIdx, CategoryType.JOB);
117 |
118 | List jobSubscribeContents = userContentsProviderList.stream()
119 | .map(m -> jobRepository.findJobByContentsProvider(m))
120 | .flatMap(List::stream)
121 | .collect(Collectors.toList());
122 |
123 | List jobRecommendList = jobSubscribeContents.stream()
124 | .filter(m -> m.isContainRecommendKeywords(userRecommendKeywords))
125 | .collect(Collectors.toList());
126 |
127 | return jobRecommendList.stream()
128 | .distinct()
129 | .map(m -> JobAlarmDto.convertEntityToDto(m))
130 | .collect(Collectors.toList());
131 | }
132 |
133 | public List getRecommendKeywords(long userIdx){
134 | List userCustomKeywords = userRepository.findUsersById(userIdx).getJob().getKeywords();
135 |
136 | Stream.of(RecommendKeywordType.values())
137 | .forEach(m -> userCustomKeywords.add(m.getName()));
138 |
139 | return userCustomKeywords;
140 | }
141 |
142 | }
143 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/ContentsService.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.core.type.TypeReference;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import com.hermes.ithermes.domain.entity.CrawlingContents;
7 | import com.hermes.ithermes.domain.entity.Job;
8 | import com.hermes.ithermes.domain.entity.YoutubeAndNews;
9 | import com.hermes.ithermes.domain.exception.JsonParseException;
10 | import com.hermes.ithermes.domain.util.CategoryType;
11 | import com.hermes.ithermes.domain.util.ElasticSearchType;
12 | import com.hermes.ithermes.domain.util.OrderType;
13 | import com.hermes.ithermes.infrastructure.JobRepository;
14 | import com.hermes.ithermes.infrastructure.YoutubeAndNewsRepository;
15 | import com.hermes.ithermes.infrastructure.elastic.JobSearchRepository;
16 | import com.hermes.ithermes.infrastructure.elastic.YoutubeAndNewsSearchRepository;
17 | import com.hermes.ithermes.presentation.dto.contents.*;
18 | import lombok.RequiredArgsConstructor;
19 | import org.springframework.cache.annotation.CacheEvict;
20 | import org.springframework.cache.annotation.Cacheable;
21 | import org.springframework.data.domain.Page;
22 | import org.springframework.data.domain.PageRequest;
23 | import org.springframework.data.domain.Pageable;
24 | import org.springframework.data.domain.Sort;
25 | import org.springframework.data.redis.core.ListOperations;
26 | import org.springframework.data.redis.core.RedisTemplate;
27 | import org.springframework.stereotype.Service;
28 | import org.springframework.transaction.annotation.Transactional;
29 |
30 | import java.util.ArrayList;
31 | import java.util.List;
32 | import java.util.concurrent.TimeUnit;
33 | import java.util.stream.Collectors;
34 |
35 | @Service
36 | @RequiredArgsConstructor
37 | @Transactional
38 | public class ContentsService {
39 |
40 | private final YoutubeAndNewsRepository youtubeAndNewsRepository;
41 | private final JobRepository jobRepository;
42 | private final RedisTemplate cacheRedisTemplate;
43 | private final ObjectMapper objectMapper;
44 | private final YoutubeAndNewsSearchRepository youtubeAndNewsSearchRepository;
45 | private final JobSearchRepository jobSearchRepository;
46 |
47 | @Cacheable("top12ContentsCache")
48 | public List getMainContents(CategoryType type) {
49 | Pageable pageInfo = PageRequest.of(0, 12, Sort.by(OrderType.POPULAR.getOrderQuery()).descending());
50 | if (type.getTitle().equals("JOB")) {
51 | return convertEntityToDtoList(jobRepository.findJobBy(pageInfo).getContent(), new MainPageContentsDto());
52 | }
53 | ListOperations stringListValueOperations = cacheRedisTemplate.opsForList();
54 | if (stringListValueOperations.size("top12") == 0) {
55 | cacheRedisTemplate.expire("top12", 60 * 60 * 3, TimeUnit.SECONDS);
56 | List contentsDtoInterfaces = pageYoutubeAndNewsConvertMainPageContentsDto(pageInfo, type);
57 | stringListValueOperations.rightPushAll("top12", contentsDtoInterfaces);
58 | return contentsDtoInterfaces;
59 | }
60 | Object range = stringListValueOperations.index("top12", 0L);
61 | try {
62 | String writeValueAsString = objectMapper.writeValueAsString(range);
63 | List contentsDtoInterfaceList = new ArrayList<>();
64 | List mainPageContentsDtoList = objectMapper.readValue(writeValueAsString, new TypeReference<>() {
65 | });
66 |
67 | mainPageContentsDtoList.stream().forEach(v -> contentsDtoInterfaceList.add(v));
68 | return contentsDtoInterfaceList;
69 | } catch (JsonProcessingException e) {
70 | throw new JsonParseException();
71 | }
72 | }
73 |
74 | public List getCategoryContents(CategoryType type, int page, OrderType order) {
75 | Pageable pageInfo = PageRequest.of(page, 12, Sort.by(order.getOrderQuery()).descending());
76 |
77 | if (type.getTitle().equals("JOB")) {
78 | return convertEntityToDtoList(jobRepository.findJobBy(pageInfo).getContent(), new ContentsDto());
79 | }
80 |
81 | return convertEntityToDtoList(youtubeAndNewsRepository.findYoutubeAndNewsByCategory(pageInfo, type).getContent(), new ContentsDto());
82 | }
83 |
84 | private List pageYoutubeAndNewsConvertMainPageContentsDto(Pageable page, CategoryType type) {
85 | Page youtubeAndNewsContents;
86 |
87 | if (type.equals(CategoryType.YOUTUBE_AND_NEWS)) {
88 | youtubeAndNewsContents = youtubeAndNewsRepository.findYoutubeAndNewsBy(page);
89 | } else {
90 | youtubeAndNewsContents = youtubeAndNewsRepository.findYoutubeAndNewsByCategory(page, type);
91 | }
92 |
93 | return convertEntityToDtoList(youtubeAndNewsContents.getContent(), new MainPageContentsDto());
94 | }
95 |
96 | private List convertEntityToDtoList(List content, ContentsDtoInterface t) {
97 | return content.stream().map(x -> t.convertEntityToDto(x)).collect(Collectors.toList());
98 | }
99 |
100 | public CategoryCountDto getCategoryCount() {
101 | Long youtubeCnt = youtubeAndNewsRepository.countYoutubeAndNewsByCategory(CategoryType.YOUTUBE);
102 | Long jobCnt = jobRepository.countBy();
103 | Long newsCnt = youtubeAndNewsRepository.countYoutubeAndNewsByCategory(CategoryType.NEWS);
104 |
105 | return new CategoryCountDto(youtubeCnt, jobCnt, newsCnt);
106 | }
107 |
108 | public SearchContentsDto getSearchContents(String title, CategoryType categoryType) {
109 | if (categoryType == CategoryType.JOB) {
110 | List jobSearchContents = jobSearchRepository.findByTitleContaining(title);
111 | return new SearchContentsDto(jobSearchContents.size(),convertEntityToDtoList(jobSearchContents, new ContentsDto()));
112 | } else {
113 | List youtubeSearchContents = youtubeAndNewsSearchRepository.findByTitleContainingAndCategory(title,categoryType);
114 | return new SearchContentsDto(youtubeSearchContents.size(),convertEntityToDtoList(youtubeSearchContents, new ContentsDto()));
115 | }
116 | }
117 |
118 | @CacheEvict(value = "top12ContentsCache", allEntries = true)
119 | public void deleteContentsCache() {
120 | }
121 |
122 | public void updateElasticsearch(){
123 | List youtubeAndNewsCrawlingContents = youtubeAndNewsRepository.findByElasticSearchType(ElasticSearchType.READY);
124 | youtubeAndNewsCrawlingContents.stream()
125 | .forEach(v -> {
126 | v.updateElasticSearchType();
127 | youtubeAndNewsSearchRepository.save(YoutubeAndNews.convertESentity(v));
128 | });
129 |
130 | List jobCrawlingContents = jobRepository.findByElasticSearchType(ElasticSearchType.READY);
131 | jobCrawlingContents.stream()
132 | .forEach(v -> {
133 | v.updateElasticSearchType();
134 | jobSearchRepository.save(Job.convertESEntitiy(v));
135 | });
136 | }
137 |
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/CrawlingContentsLastUrlService.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContentsLastUrl;
4 | import com.hermes.ithermes.domain.factory.CrawlingContentsLastUrlFactory;
5 | import com.hermes.ithermes.presentation.dto.crawlingcontentslasttitle.CrawlingContentsLastUrlFindAllResponseDto;
6 | import lombok.RequiredArgsConstructor;
7 | import org.springframework.stereotype.Service;
8 | import org.springframework.transaction.annotation.Transactional;
9 |
10 | import java.util.List;
11 |
12 | @Service
13 | @RequiredArgsConstructor
14 | @Transactional(readOnly = true)
15 | public class CrawlingContentsLastUrlService {
16 | private final CrawlingContentsLastUrlFactory crawlingContentsLastUrlFactory;
17 |
18 | public CrawlingContentsLastUrlFindAllResponseDto findAllCrawlingContentsLastTitle() {
19 | List crawlingContentsLastTitles = crawlingContentsLastUrlFactory.parseAllCrawlingContentsLastTitle();
20 | return new CrawlingContentsLastUrlFindAllResponseDto(crawlingContentsLastTitles);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/ExternalAlarmClient.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.presentation.dto.alarm.AlarmDtoInterface;
4 | import com.hermes.ithermes.presentation.dto.alarm.JobAlarmDto;
5 | import com.hermes.ithermes.presentation.dto.alarm.YoutubeAndNewsAlarmDto;
6 |
7 | import java.util.List;
8 |
9 | public interface ExternalAlarmClient {
10 |
11 | void sendContentsMessage(List youtubeAlarmDtoList, String telegramId);
12 | void sendJobMessage(List jobAlarmDtoList, String telegramId);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/JobService.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContentsLastUrl;
4 | import com.hermes.ithermes.domain.entity.Job;
5 | import com.hermes.ithermes.domain.exception.NoCrawlingDataException;
6 | import com.hermes.ithermes.domain.factory.CrawlingContentsLastUrlFactory;
7 | import com.hermes.ithermes.domain.factory.JobFactory;
8 | import com.hermes.ithermes.domain.util.ContentsProviderType;
9 | import com.hermes.ithermes.domain.util.GradeType;
10 | import com.hermes.ithermes.domain.util.JobType;
11 | import com.hermes.ithermes.infrastructure.CrawlingContentsLastUrlRepository;
12 | import com.hermes.ithermes.infrastructure.JobRepository;
13 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
14 | import com.hermes.ithermes.presentation.dto.job.JobInsertRequestDto;
15 | import lombok.RequiredArgsConstructor;
16 | import org.checkerframework.checker.units.qual.C;
17 | import org.springframework.stereotype.Service;
18 | import org.springframework.transaction.annotation.Transactional;
19 |
20 | import java.util.List;
21 | import java.util.Optional;
22 |
23 | @Service
24 | @RequiredArgsConstructor
25 | @Transactional(readOnly = true)
26 | public class JobService {
27 | private final JobFactory jobFactory;
28 | private final JobRepository jobRepository;
29 | private final CrawlingContentsLastUrlFactory crawlingContentsLastUrlFactory;
30 | private final CrawlingContentsLastUrlRepository crawlingContentsLastUrlRepository;
31 |
32 | @Transactional
33 | public CommonResponseDto insertJob(JobInsertRequestDto jobInsertRequestDto) {
34 | if (jobInsertRequestDto.getJobCrawlingDtoList().isEmpty()) throw new NoCrawlingDataException();
35 |
36 | List jobList = jobFactory.insertJob(jobInsertRequestDto);
37 | jobList.stream().forEach(v -> jobRepository.save(v));
38 |
39 | Job recentJob = jobList.get(0);
40 |
41 | ContentsProviderType contentsProvider = recentJob.getContentsProvider();
42 | GradeType grade = recentJob.getGrade();
43 | JobType jobType = jobInsertRequestDto.getJob();
44 |
45 | Optional contentsLastTitle = crawlingContentsLastUrlRepository.findByContentsProviderAndGradeAndJob(contentsProvider, grade, jobType);
46 | CrawlingContentsLastUrl recentCrawlingContentsLastUrl = crawlingContentsLastUrlFactory.parseCrawlingContentsLastUrlToJob(recentJob, jobType);
47 |
48 | contentsLastTitle.ifPresentOrElse(
49 | v -> {
50 | v.updateLastUrl(recentCrawlingContentsLastUrl);
51 | },
52 | () -> {
53 | crawlingContentsLastUrlRepository.save(recentCrawlingContentsLastUrl);
54 | }
55 | );
56 | return new CommonResponseDto();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/SubscribeService.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.domain.entity.Subscribe;
4 | import com.hermes.ithermes.domain.factory.SubscribeFactory;
5 | import com.hermes.ithermes.infrastructure.SubscribeRepository;
6 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
7 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeContentsDto;
8 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeFindSubscribeRequestDto;
9 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribePutSubscribeRequestDto;
10 | import lombok.RequiredArgsConstructor;
11 | import org.springframework.stereotype.Service;
12 | import org.springframework.transaction.annotation.Transactional;
13 |
14 | import java.util.List;
15 |
16 | @Service
17 | @RequiredArgsConstructor
18 | @Transactional(readOnly = true)
19 | public class SubscribeService {
20 | private final SubscribeRepository subscribeRepository;
21 | private final SubscribeFactory subscribeFactory;
22 |
23 | @Transactional
24 | public CommonResponseDto putSubscribe(SubscribePutSubscribeRequestDto subscribePutSubscribeRequestDto) {
25 | List subscribes = subscribeFactory.parsePutSubscribeDtoToSubscribes(subscribePutSubscribeRequestDto);
26 | subscribes.stream().forEach(v -> subscribeRepository.save(v));
27 | return new CommonResponseDto();
28 | }
29 |
30 | public List findSubscribe(SubscribeFindSubscribeRequestDto subscribeFindSubScribeRequestDto) {
31 | List subscribes = subscribeFactory.parseFindSubscribeDtoToSubscribes(subscribeFindSubScribeRequestDto);
32 | List contentsProviderTypes = SubscribeFactory.findActiveContentsProviderType(subscribes);
33 |
34 | return contentsProviderTypes;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/TelegramAlarm.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.infrastructure.*;
4 | import com.hermes.ithermes.presentation.dto.alarm.AlarmDtoInterface;
5 | import com.hermes.ithermes.presentation.dto.alarm.JobAlarmDto;
6 | import com.pengrad.telegrambot.TelegramBot;
7 | import com.pengrad.telegrambot.request.SendMessage;
8 | import lombok.RequiredArgsConstructor;
9 | import org.springframework.stereotype.Component;
10 |
11 | import java.util.List;
12 |
13 | @Component
14 | @RequiredArgsConstructor
15 | public class TelegramAlarm implements ExternalAlarmClient {
16 | private final TelegramBot telegramBot;
17 |
18 | private final UserRepository userRepository;
19 |
20 | @Override
21 | public void sendContentsMessage(List contentsAlarmDtoList, String telegramId) {
22 |
23 | for(int i = 0; i < contentsAlarmDtoList.size(); i++){
24 | StringBuilder youtubeAlarmMessage = new StringBuilder();
25 |
26 | youtubeAlarmMessage.append("[유투브 및 뉴스 정보]" + "\n")
27 | .append("[제목]" + contentsAlarmDtoList.get(i).title() + "\n")
28 | .append("[본문]" + contentsAlarmDtoList.get(i).description() + "\n")
29 | .append("[이미지]" + contentsAlarmDtoList.get(i).image() + "\n")
30 | .append("[url]" + contentsAlarmDtoList.get(i).url() + "\n")
31 | .append("[일자]" + contentsAlarmDtoList.get(i).contentsStartAt() + "\n")
32 | .append("[서비스]" + contentsAlarmDtoList.get(i).contentsProvider() + "\n");
33 |
34 | telegramBot.execute(new SendMessage(telegramId,youtubeAlarmMessage.toString()));
35 | }
36 |
37 | }
38 |
39 | @Override
40 | public void sendJobMessage(List jobAlarmDtoList, String telegramId) {
41 |
42 | for(int i = 0; i < jobAlarmDtoList.size(); i++) {
43 | StringBuilder jobAlarmMessage = new StringBuilder();
44 |
45 | jobAlarmMessage.append("[채용 정보]" + "\n")
46 | .append("[제목]" + jobAlarmDtoList.get(i).getTitle() + "\n")
47 | .append("[회사]" + jobAlarmDtoList.get(i).getCompany() + "\n")
48 | .append("[위치]" + jobAlarmDtoList.get(i).getLocation() + "\n")
49 | .append("[url]" + jobAlarmDtoList.get(i).getUrl() + "\n")
50 | .append("[서비스]" + jobAlarmDtoList.get(i).getContentsProviderType() + "\n")
51 | .append("[마감일]" + jobAlarmDtoList.get(i).getContentsEndAt());
52 |
53 | telegramBot.execute(new SendMessage(telegramId,jobAlarmMessage.toString()));
54 | }
55 |
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/UpdateUserChatId.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.domain.entity.User;
4 | import com.hermes.ithermes.infrastructure.UserRepository;
5 | import com.pengrad.telegrambot.TelegramBot;
6 | import com.pengrad.telegrambot.UpdatesListener;
7 | import com.pengrad.telegrambot.model.Update;
8 | import com.pengrad.telegrambot.request.SendMessage;
9 | import lombok.RequiredArgsConstructor;
10 |
11 | import java.util.List;
12 |
13 | @RequiredArgsConstructor
14 | public class UpdateUserChatId {
15 | private final TelegramBot telegramBot;
16 |
17 | public void updateUserChatId(UserRepository userRepository){
18 | telegramBot.setUpdatesListener(new UpdatesListener() {
19 | @Override
20 | public int process(List updates) {
21 | for(Update update : updates){
22 | String chatId = update.message().chat().id().toString();
23 | String userSendMessage = update.message().text();
24 |
25 | if(userSendMessage.equals("/start")){
26 | telegramBot.execute(new SendMessage(chatId, "IT-Hermes에서 사용하는 닉네임을 입력해주세요."));
27 | return UpdatesListener.CONFIRMED_UPDATES_ALL;
28 | }
29 |
30 | if(userRepository.existsUserByNickname(userSendMessage) == false){
31 | telegramBot.execute(new SendMessage(chatId,"존재하지 않는 유저입니다. 먼저 회원가입을 진행해주세요."));
32 | return UpdatesListener.CONFIRMED_UPDATES_ALL;
33 | }
34 |
35 | if(userRepository.existsUserByNicknameAndTelegramId(chatId,userSendMessage) == true){
36 | telegramBot.execute(new SendMessage(chatId,"이미 생성한 봇이 있는 유저입니다."));
37 | }else{
38 | User newUser = userRepository.findByNickname(userSendMessage);
39 | newUser.updateTelegramId(chatId);
40 | userRepository.save(newUser);
41 | telegramBot.execute(new SendMessage(chatId,"유저로 등록되었습니다."));
42 | }
43 |
44 | return UpdatesListener.CONFIRMED_UPDATES_ALL;
45 | }
46 |
47 | return UpdatesListener.CONFIRMED_UPDATES_ALL;
48 | }
49 |
50 | });
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/UrlRecordService.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.domain.entity.Job;
4 | import com.hermes.ithermes.domain.entity.UrlRecord;
5 | import com.hermes.ithermes.domain.entity.YoutubeAndNews;
6 | import com.hermes.ithermes.domain.exception.NoCrawlingDataException;
7 | import com.hermes.ithermes.domain.factory.UrlRecordFactory;
8 | import com.hermes.ithermes.infrastructure.JobRepository;
9 | import com.hermes.ithermes.infrastructure.UrlRecordRepository;
10 | import com.hermes.ithermes.infrastructure.YoutubeAndNewsRepository;
11 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
12 | import com.hermes.ithermes.presentation.dto.urlrecord.UrlRecordPutViewCountRequestDto;
13 | import lombok.RequiredArgsConstructor;
14 | import org.springframework.stereotype.Service;
15 | import org.springframework.transaction.annotation.Transactional;
16 |
17 | import java.util.List;
18 |
19 | @Service
20 | @RequiredArgsConstructor
21 | @Transactional(readOnly = true)
22 | public class UrlRecordService {
23 | private final UrlRecordRepository urlRecordRepository;
24 | private final UrlRecordFactory urlRecordFactory;
25 | private final JobRepository jobRepository;
26 | private final YoutubeAndNewsRepository youtubeAndNewsRepository;
27 |
28 | @Transactional
29 | public CommonResponseDto putViewCount(UrlRecordPutViewCountRequestDto urlRecordPutViewCountRequestDto, String ipAddress) {
30 | String url = urlRecordPutViewCountRequestDto.getUrl();
31 | boolean existsView = urlRecordRepository.existsByUrlAndClientIpAddress(url, ipAddress);
32 | if (existsView) return new CommonResponseDto();
33 |
34 | UrlRecord urlRecord = urlRecordFactory.parseUrlRecord(urlRecordPutViewCountRequestDto, ipAddress);
35 | urlRecordRepository.save(urlRecord);
36 | List jobList = jobRepository.findByUrl(url).orElseThrow(() -> new NoCrawlingDataException());
37 |
38 | if (jobList.isEmpty()) {
39 | List youtubeAndNewsList = youtubeAndNewsRepository.findByUrl(url).orElseThrow(() -> new NoCrawlingDataException());
40 | if (!youtubeAndNewsList.isEmpty()) youtubeAndNewsList.stream().forEach(youtubeAndNews -> youtubeAndNews.updateViewCount());
41 | } else {
42 | jobList.stream().forEach(job -> job.updateViewCount());
43 | }
44 |
45 | return new CommonResponseDto();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/UserService.java:
--------------------------------------------------------------------------------
1 |
2 | package com.hermes.ithermes.application;
3 |
4 | import com.hermes.ithermes.domain.entity.Keyword;
5 | import com.hermes.ithermes.domain.entity.User;
6 | import com.hermes.ithermes.domain.entity.UserKeywordRegistry;
7 | import com.hermes.ithermes.domain.exception.*;
8 | import com.hermes.ithermes.domain.factory.KeywordFactory;
9 | import com.hermes.ithermes.domain.factory.RedisFactory;
10 | import com.hermes.ithermes.domain.factory.UserFactory;
11 | import com.hermes.ithermes.domain.factory.UserKeywordRegistryFactory;
12 | import com.hermes.ithermes.infrastructure.UserKeywordRegistryRepository;
13 | import com.hermes.ithermes.infrastructure.UserRepository;
14 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
15 | import com.hermes.ithermes.presentation.dto.user.*;
16 | import com.hermes.ithermes.presentation.security.JwtUtil;
17 | import lombok.RequiredArgsConstructor;
18 | import org.springframework.beans.factory.annotation.Value;
19 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
20 | import org.springframework.stereotype.Service;
21 | import org.springframework.transaction.annotation.Transactional;
22 |
23 | import java.util.Arrays;
24 | import java.util.List;
25 | import java.util.Objects;
26 | import java.util.Optional;
27 |
28 | @Service
29 | @RequiredArgsConstructor
30 | @Transactional(readOnly = true)
31 | public class UserService {
32 | @Value("${springboot.jwt.secret}")
33 | private String secretKey = "secretKey";
34 |
35 | private final UserKeywordRegistryRepository userKeywordRegistryRepository;
36 | private final UserFactory userFactory;
37 | private final KeywordFactory keywordFactory;
38 | private final UserRepository userRepository;
39 | private final UserKeywordRegistryFactory userKeywordRegistryFactory;
40 | private final JwtUtil jwtUtil;
41 | private final BCryptPasswordEncoder encoder;
42 | private final RedisFactory redisFactory;
43 |
44 | @Transactional
45 | public CommonResponseDto joinUser(UserCreateUserRequestDto userLoginRequestDto) {
46 |
47 | Optional.ofNullable(userLoginRequestDto.getPassword().equals(userLoginRequestDto.getPasswordConfirm()))
48 | .filter(v -> v)
49 | .orElseThrow(() -> new UnMatchedPasswordException());
50 |
51 | String loginId = userLoginRequestDto.getId();
52 | String password = encoder.encode(userLoginRequestDto.getPassword());
53 | userLoginRequestDto.encodingPassword(password);
54 |
55 | if (userFactory.existsByLoginId(loginId)) throw new SameIdException();
56 | User user = userFactory.parseLoginRequestDtoToUser(userLoginRequestDto);
57 |
58 | Arrays.stream(userLoginRequestDto.getKeywordList())
59 | .filter(v -> Objects.nonNull(v))
60 | .forEach(v -> {
61 | Keyword keyword = keywordFactory.parseKeywordNameToKeyword(v);
62 | UserKeywordRegistry userKeywordRegistry = userKeywordRegistryFactory.parseUserAndKeyword(user, keyword);
63 | userKeywordRegistryRepository.save(userKeywordRegistry);
64 | });
65 |
66 | return new CommonResponseDto();
67 | }
68 |
69 | @Transactional
70 | public UserLoginResponseDto loginUser(UserLoginRequestDto userLoginRequestDto) {
71 | String loginId = userLoginRequestDto.getId();
72 | String password = userLoginRequestDto.getPassword();
73 |
74 | User user = userFactory.findLoginId(loginId).orElseThrow(() -> new WrongIdOrPasswordException());
75 |
76 | if (!encoder.matches(password, user.getPassword())) throw new WrongIdOrPasswordException();
77 |
78 | String refreshToken = jwtUtil.createRefreshToken(loginId);
79 | redisFactory.setRedisRefreshToken(loginId, refreshToken);
80 |
81 | UserLoginResponseDto userLoginResponseDto = UserLoginResponseDto.builder()
82 | .message("success")
83 | .accessToken(jwtUtil.createAccessToken(loginId))
84 | .refreshToken(refreshToken)
85 | .build();
86 |
87 | return userLoginResponseDto;
88 | }
89 |
90 | public CommonResponseDto checkDuplicateNickname(UserDuplicateNicknameRequestDto userDuplicateNicknameRequestDto) {
91 | String nickname = userDuplicateNicknameRequestDto.getNickname();
92 | if (userRepository.existsByNickname(nickname)) throw new SameNicknameException();
93 | return new CommonResponseDto();
94 | }
95 |
96 | public CommonResponseDto checkDuplicateId(UserDuplicateIdRequestDto userDuplicateIdRequestDto) {
97 | String loginId = userDuplicateIdRequestDto.getId();
98 | if (userFactory.existsByLoginId(loginId)) throw new SameIdException();
99 | return new CommonResponseDto();
100 | }
101 |
102 | @Transactional
103 | public CommonResponseDto updateNickname(UserUpdateNicknameRequestDto userUpdateNicknameRequestDto) {
104 | String newNickname = userUpdateNicknameRequestDto.getNickname();
105 | if (userFactory.existsByNickname(newNickname)) throw new SameNicknameException();
106 |
107 | User user = userFactory.findLoginId(userUpdateNicknameRequestDto.getId()).orElseThrow(() -> new WrongIdOrPasswordException());
108 | user.updateNickname(newNickname);
109 | return new CommonResponseDto();
110 | }
111 |
112 | @Transactional
113 | public CommonResponseDto deleteUser(UserDeleteUserRequestDto userDeleteUserRequestDto) {
114 | User user = userFactory.findLoginId(userDeleteUserRequestDto.getId()).orElseThrow(() -> new WrongIdOrPasswordException());
115 |
116 | user.isDelete();
117 | return new CommonResponseDto();
118 | }
119 |
120 | public UserFindMyDataResponseDto findMyData(UserFindMyDataRequestDto userFindMyDataRequestDto) {
121 | User user = userFactory.findLoginId(userFindMyDataRequestDto.getId()).orElseThrow(() -> new WrongIdOrPasswordException());
122 | return new UserFindMyDataResponseDto(user.getLoginId(), user.getNickname());
123 | }
124 |
125 | public UserCheckRefreshTokenResponseDto checkRefreshToken(String refreshToken) {
126 | String token = refreshToken.split(" ")[1];
127 | boolean validateToken = jwtUtil.validateToken(token, secretKey);
128 | if (!validateToken) {
129 | throw new ExpireTokenException();
130 | }
131 | String loginId = JwtUtil.getUsername(token, secretKey);
132 | String redisRefreshToken = redisFactory.getRedisRefreshToken(loginId);
133 | /** 레디스 캐쉬 존재 유무 확인 */
134 | if (!token.equals(redisRefreshToken)) throw new ExpireTokenException();
135 |
136 | String accessToken = jwtUtil.createAccessToken(loginId);
137 | return UserCheckRefreshTokenResponseDto
138 | .builder()
139 | .accessToken(accessToken)
140 | .message("success")
141 | .build();
142 | }
143 |
144 | @Transactional
145 | public CommonResponseDto userLogout(String loginId) {
146 | redisFactory.deleteRedisRefreshToken(loginId);
147 | return new CommonResponseDto();
148 | }
149 |
150 | public List findUserList() {
151 | List userAndSubscribe = userRepository.findUserAndSubscribe();
152 | return userAndSubscribe.stream().map(user -> UserFactory.parseUserToRequestUserDto(user)).toList();
153 | }
154 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/application/YoutubeAndNewsService.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContentsLastUrl;
4 | import com.hermes.ithermes.domain.entity.YoutubeAndNews;
5 | import com.hermes.ithermes.domain.exception.NoCrawlingDataException;
6 | import com.hermes.ithermes.domain.factory.CrawlingContentsLastUrlFactory;
7 | import com.hermes.ithermes.domain.factory.YoutubeAndNewsFactory;
8 | import com.hermes.ithermes.domain.util.ContentsProviderType;
9 | import com.hermes.ithermes.infrastructure.CrawlingContentsLastUrlRepository;
10 | import com.hermes.ithermes.infrastructure.YoutubeAndNewsRepository;
11 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
12 | import com.hermes.ithermes.presentation.dto.youtubeandnews.YoutubeAndNewsInsertDto;
13 | import lombok.RequiredArgsConstructor;
14 | import org.springframework.stereotype.Service;
15 | import org.springframework.transaction.annotation.Transactional;
16 |
17 | import java.util.List;
18 | import java.util.Optional;
19 |
20 | @Service
21 | @RequiredArgsConstructor
22 | @Transactional(readOnly = true)
23 | public class YoutubeAndNewsService {
24 | private final YoutubeAndNewsFactory youtubeAndNewsFactory;
25 | private final YoutubeAndNewsRepository youtubeAndNewsRepository;
26 | private final CrawlingContentsLastUrlFactory crawlingContentsLastUrlFactory;
27 | private final CrawlingContentsLastUrlRepository crawlingContentsLastUrlRepository;
28 |
29 | @Transactional
30 | public CommonResponseDto insertYoutubeAndNews(YoutubeAndNewsInsertDto youtubeAndNewsCrawlingDtoList) {
31 | if(youtubeAndNewsCrawlingDtoList.getYoutubeAndNewsCrawlingDtoList().isEmpty()) throw new NoCrawlingDataException();
32 |
33 | List youtubeAndNewsList = youtubeAndNewsFactory.parseYoutubeAndNews(youtubeAndNewsCrawlingDtoList);
34 | youtubeAndNewsList.stream().forEach(v -> youtubeAndNewsRepository.save(v));
35 |
36 | YoutubeAndNews recentYoutubeAndNews = youtubeAndNewsList.get(0);
37 |
38 | ContentsProviderType contentsProvider = recentYoutubeAndNews.getContentsProvider();
39 | Optional contentsLastTitle = crawlingContentsLastUrlRepository.findByContentsProvider(contentsProvider);
40 | CrawlingContentsLastUrl recentCrawlingContentsLastUrl = crawlingContentsLastUrlFactory.parseCrawlingContentsLastUrlToYoutubeAndNews(recentYoutubeAndNews);
41 |
42 | contentsLastTitle.ifPresentOrElse(
43 | v -> {
44 | v.updateLastUrl(recentCrawlingContentsLastUrl);
45 | },
46 | () -> {
47 | crawlingContentsLastUrlRepository.save(recentCrawlingContentsLastUrl);
48 | }
49 | );
50 | return new CommonResponseDto();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/AlarmSearch.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import com.hermes.ithermes.domain.util.CategoryType;
4 | import com.hermes.ithermes.domain.util.ContentsProviderType;
5 | import jakarta.persistence.Id;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Getter;
9 | import lombok.NoArgsConstructor;
10 | import org.springframework.data.elasticsearch.annotations.Document;
11 |
12 | @Getter
13 | @Builder
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | @Document(indexName = "alarmsearch")
17 | public class AlarmSearch {
18 |
19 | @Id
20 | private String id;
21 |
22 | private ContentsProviderType contentsProvider;
23 |
24 | private Long userId;
25 |
26 | private CategoryType category;
27 |
28 | private String telegramId;
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/BaseEntity.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import jakarta.persistence.*;
4 | import lombok.Getter;
5 | import org.springframework.data.jpa.domain.support.AuditingEntityListener;
6 |
7 | import java.time.LocalDateTime;
8 |
9 | @Getter
10 | @MappedSuperclass
11 | @EntityListeners(AuditingEntityListener.class)
12 | public class BaseEntity {
13 |
14 | @Temporal(TemporalType.TIMESTAMP)
15 | private LocalDateTime createdAt;
16 |
17 | @Temporal(TemporalType.TIMESTAMP)
18 | private LocalDateTime updatedAt;
19 |
20 | @PrePersist
21 | public void prePersist() {
22 | var nowTime = LocalDateTime.now();
23 | this.createdAt = nowTime;
24 | this.updatedAt = nowTime;
25 | }
26 |
27 | public void changeUpdateAt() {
28 | this.updatedAt = LocalDateTime.now();
29 | }
30 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/ContentsViewMapping.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import jakarta.persistence.*;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Getter;
7 | import lombok.RequiredArgsConstructor;
8 |
9 | @Entity
10 | @Getter
11 | @Builder
12 | @RequiredArgsConstructor
13 | @AllArgsConstructor
14 | public class ContentsViewMapping extends BaseEntity {
15 | @Id
16 | @GeneratedValue(strategy = GenerationType.IDENTITY)
17 | private Long id;
18 |
19 | @Column(nullable = false)
20 | private String url;
21 |
22 | @Column(nullable = false)
23 | private String pc;
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/CrawlingContents.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import com.hermes.ithermes.domain.util.CategoryType;
4 | import com.hermes.ithermes.domain.util.ContentsProviderType;
5 |
6 | import java.time.LocalDateTime;
7 |
8 |
9 | public interface CrawlingContents {
10 |
11 | String findTitle();
12 | String findImage();
13 | String findUrl();
14 | CategoryType findCategoryType();
15 | ContentsProviderType findContentsProvider();
16 | LocalDateTime findContentsTime();
17 | String findDescription();
18 | Long findViewCount();
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/CrawlingContentsLastUrl.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import com.hermes.ithermes.domain.util.ContentsProviderType;
4 | import com.hermes.ithermes.domain.util.GradeType;
5 | import com.hermes.ithermes.domain.util.JobType;
6 | import jakarta.persistence.*;
7 | import lombok.AllArgsConstructor;
8 | import lombok.Builder;
9 | import lombok.Getter;
10 | import lombok.RequiredArgsConstructor;
11 |
12 | @Entity
13 | @Getter
14 | @Builder
15 | @RequiredArgsConstructor
16 | @AllArgsConstructor
17 | public class CrawlingContentsLastUrl {
18 | @Id
19 | @GeneratedValue(strategy = GenerationType.IDENTITY)
20 | private Long id;
21 |
22 | @Enumerated(EnumType.STRING)
23 | @Column(nullable = false)
24 | private ContentsProviderType contentsProvider;
25 |
26 | @Enumerated(EnumType.STRING)
27 | private GradeType grade;
28 |
29 | @Enumerated(EnumType.STRING)
30 | private JobType job;
31 |
32 | @Column(nullable = false, length = 1000)
33 | private String lastUrl;
34 |
35 | public void updateLastUrl(CrawlingContentsLastUrl crawlingContentsLastUrl) {
36 | this.lastUrl = crawlingContentsLastUrl.getLastUrl();
37 | }
38 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/Job.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.hermes.ithermes.domain.util.*;
5 | import jakarta.persistence.*;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Getter;
9 | import lombok.NoArgsConstructor;
10 |
11 | import java.time.LocalDateTime;
12 | import java.util.List;
13 |
14 | @Entity
15 | @Getter
16 | @Builder
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | public class Job extends BaseEntity implements CrawlingContents {
20 |
21 | @Version
22 | private Integer version;
23 |
24 | @Id
25 | @GeneratedValue(strategy = GenerationType.IDENTITY)
26 | private Long id;
27 |
28 | @Column(nullable = false)
29 | private String title;
30 |
31 | @Column(nullable = false)
32 | private String url;
33 |
34 | @Column(nullable = false)
35 | private String location;
36 |
37 | @Column(nullable = false)
38 | private String company;
39 |
40 | @Temporal(TemporalType.TIMESTAMP)
41 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
42 | @Column(nullable = false)
43 | private LocalDateTime contentsStartAt;
44 |
45 | @Temporal(TemporalType.TIMESTAMP)
46 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
47 | @Column(nullable = false)
48 | private LocalDateTime contentsEndAt;
49 |
50 | @Column(nullable = false)
51 | private Long viewCount;
52 |
53 | @Column(nullable = false)
54 | private Boolean isDelete;
55 |
56 | @Enumerated(EnumType.STRING)
57 | @Column(nullable = false)
58 | private ContentsProviderType contentsProvider;
59 |
60 | @Enumerated(EnumType.STRING)
61 | @Column(nullable = false)
62 | private GradeType grade;
63 |
64 | @Enumerated(EnumType.STRING)
65 | @Column(nullable = false)
66 | private JobType jobType;
67 |
68 | @Enumerated(EnumType.STRING)
69 | @Column(nullable = false, columnDefinition = "READY")
70 | private ElasticSearchType elasticSearchType;
71 |
72 | public void initDefaultData() {
73 | viewCount=0L;
74 | }
75 |
76 | public void updateViewCount() {
77 | this.viewCount+=1L;
78 | }
79 |
80 | public void updateElasticSearchType() {this.elasticSearchType=ElasticSearchType.DONE; }
81 |
82 | @Override
83 | public String findTitle() {
84 | return title;
85 | }
86 |
87 | @Override
88 | public String findImage() {
89 | return null;
90 | }
91 |
92 | @Override
93 | public String findUrl() {
94 | return url;
95 | }
96 |
97 | @Override
98 | public CategoryType findCategoryType() {
99 | return CategoryType.JOB;
100 | }
101 |
102 | @Override
103 | public ContentsProviderType findContentsProvider() {
104 | return contentsProvider;
105 | }
106 |
107 | @Override
108 | public LocalDateTime findContentsTime() {
109 | return contentsEndAt;
110 | }
111 |
112 | @Override
113 | public String findDescription() {
114 | return company;
115 | }
116 |
117 | public boolean isContainRecommendKeywords(List keywordList){
118 | return keywordList.stream()
119 | .anyMatch(m->m.contains(title));
120 | }
121 |
122 | @Override
123 | public Long findViewCount() {
124 | return viewCount;
125 | }
126 |
127 | public static JobSearch convertESEntitiy(Job job){
128 | return JobSearch.builder()
129 | .title(job.getTitle())
130 | .url(job.getUrl())
131 | .location(job.getLocation())
132 | .company(job.getCompany())
133 | .contentsStartAt(job.getContentsStartAt())
134 | .contentsEndAt(job.getContentsEndAt())
135 | .viewCount(job.getViewCount())
136 | .isDelete(job.getIsDelete())
137 | .contentsProvider(job.getContentsProvider())
138 | .grade(job.getGrade())
139 | .jobType(job.getJobType())
140 | .build();
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/JobSearch.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.hermes.ithermes.domain.util.*;
5 | import jakarta.persistence.*;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Getter;
9 | import lombok.NoArgsConstructor;
10 | import org.springframework.data.elasticsearch.annotations.DateFormat;
11 | import org.springframework.data.elasticsearch.annotations.Document;
12 | import org.springframework.data.elasticsearch.annotations.Field;
13 | import org.springframework.data.elasticsearch.annotations.FieldType;
14 |
15 | import java.time.LocalDateTime;
16 |
17 | @Getter
18 | @Builder
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Document(indexName = "jobsearch")
22 | public class JobSearch extends BaseEntity implements CrawlingContents {
23 |
24 | @Id
25 | private String id;
26 |
27 | @Column(nullable = false)
28 | private String title;
29 |
30 | @Column(nullable = false)
31 | private String url;
32 |
33 | @Column(nullable = false)
34 | private String location;
35 |
36 | @Column(nullable = false)
37 | private String company;
38 |
39 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
40 | @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss")
41 | private LocalDateTime contentsStartAt;
42 |
43 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
44 | @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss")
45 | private LocalDateTime contentsEndAt;
46 |
47 | @Column(nullable = false)
48 | private Long viewCount;
49 |
50 | @Column(nullable = false)
51 | private Boolean isDelete;
52 |
53 | @Enumerated(EnumType.STRING)
54 | @Column(nullable = false)
55 | private ContentsProviderType contentsProvider;
56 |
57 | @Enumerated(EnumType.STRING)
58 | @Column(nullable = false)
59 | private GradeType grade;
60 |
61 | @Enumerated(EnumType.STRING)
62 | @Column(nullable = false)
63 | private JobType jobType;
64 |
65 | @Enumerated(EnumType.STRING)
66 | private ElasticSearchType elasticSearchType;
67 |
68 | @Override
69 | public String findTitle() {
70 | return title;
71 | }
72 |
73 | @Override
74 | public String findImage() {
75 | return null;
76 | }
77 |
78 | @Override
79 | public String findUrl() {
80 | return url;
81 | }
82 |
83 | @Override
84 | public CategoryType findCategoryType() {
85 | return CategoryType.JOB;
86 | }
87 |
88 | @Override
89 | public ContentsProviderType findContentsProvider() {
90 | return contentsProvider;
91 | }
92 |
93 | @Override
94 | public LocalDateTime findContentsTime() {
95 | return contentsEndAt;
96 | }
97 |
98 | @Override
99 | public String findDescription() {
100 | return company;
101 | }
102 |
103 | @Override
104 | public Long findViewCount() {
105 | return viewCount;
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/Keyword.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import jakarta.persistence.*;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Getter;
7 | import lombok.RequiredArgsConstructor;
8 |
9 | @Entity
10 | @Getter
11 | @Builder
12 | @RequiredArgsConstructor
13 | @AllArgsConstructor
14 | public class Keyword extends BaseEntity {
15 | @Id
16 | @GeneratedValue(strategy = GenerationType.IDENTITY)
17 | private Long id;
18 |
19 | @Column(nullable = false)
20 | private String name;
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/Subscribe.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import com.hermes.ithermes.domain.util.ActiveType;
4 | import com.hermes.ithermes.domain.util.CategoryType;
5 | import com.hermes.ithermes.domain.util.ContentsProviderType;
6 | import jakarta.persistence.*;
7 | import lombok.AllArgsConstructor;
8 | import lombok.Builder;
9 | import lombok.Getter;
10 | import lombok.NoArgsConstructor;
11 |
12 | @Entity
13 | @Getter
14 | @Builder
15 | @NoArgsConstructor
16 | @AllArgsConstructor
17 |
18 | public class Subscribe extends BaseEntity {
19 | @Id
20 | @GeneratedValue(strategy = GenerationType.IDENTITY)
21 | private Long id;
22 |
23 | @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
24 | @JoinColumn(name = "userId")
25 | private User user;
26 |
27 | @Enumerated(EnumType.STRING)
28 | @Column(nullable = false)
29 | private ActiveType isActive;
30 |
31 | @Enumerated(EnumType.STRING)
32 | @Column(nullable = false)
33 | private CategoryType category;
34 |
35 | @Enumerated(EnumType.STRING)
36 | @Column(nullable = false)
37 | private ContentsProviderType contentsProvider;
38 |
39 | public void setUser(User user) {
40 | this.user = user;
41 | }
42 |
43 | public void changeUpdateAt(ActiveType activeType) {
44 | this.isActive = activeType;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/UrlRecord.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import jakarta.persistence.*;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Getter;
7 | import lombok.RequiredArgsConstructor;
8 |
9 | @Entity
10 | @Getter
11 | @Builder
12 | @RequiredArgsConstructor
13 | @AllArgsConstructor
14 | public class UrlRecord extends BaseEntity {
15 | @Id
16 | @GeneratedValue(strategy = GenerationType.IDENTITY)
17 | private Long id;
18 |
19 | @Column(nullable = false)
20 | private String url;
21 |
22 | @Column(nullable = false)
23 | private String clientIpAddress;
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/User.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import com.hermes.ithermes.domain.util.JobType;
4 | import jakarta.persistence.*;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Getter;
8 | import lombok.RequiredArgsConstructor;
9 | import org.hibernate.annotations.Where;
10 |
11 | import java.util.List;
12 |
13 | @Entity
14 | @Getter
15 | @Builder
16 | @RequiredArgsConstructor
17 | @AllArgsConstructor
18 | @Where(clause = "isDelete = false")
19 | public class User extends BaseEntity {
20 |
21 | @Id
22 | @GeneratedValue(strategy = GenerationType.IDENTITY)
23 | private Long id;
24 |
25 | @Column(nullable = false)
26 | private String nickname;
27 |
28 | @Column(nullable = false)
29 | private String loginId;
30 |
31 | @Column(nullable = false)
32 | private String password;
33 |
34 | @Enumerated(EnumType.STRING)
35 | @Column(nullable = false)
36 | private JobType job;
37 |
38 | @Column(nullable = false)
39 | private Integer yearOfExperience;
40 |
41 | private String telegramId;
42 |
43 | @Column(nullable = false)
44 | private Boolean isDelete;
45 |
46 | public void updateNickname(String nickname) {
47 | this.nickname = nickname;
48 | }
49 |
50 | public void isDelete() {
51 | this.isDelete = true;
52 | }
53 | @OneToMany(fetch = FetchType.LAZY)
54 | @JoinColumn(name = "userId")
55 | List subscribe;
56 |
57 | public void setSubscribe(List subscribe) {
58 | this.subscribe = subscribe;
59 | }
60 |
61 | public void updateTelegramId(String telegramId) {
62 | this.telegramId = telegramId;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/UserKeywordRegistry.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import jakarta.persistence.*;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Getter;
7 | import lombok.RequiredArgsConstructor;
8 |
9 | @Entity
10 | @Getter
11 | @Builder
12 | @RequiredArgsConstructor
13 | @AllArgsConstructor
14 | public class UserKeywordRegistry extends BaseEntity {
15 | @Id
16 | @GeneratedValue(strategy = GenerationType.IDENTITY)
17 | private Long id;
18 |
19 | @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
20 | @JoinColumn(name = "userId")
21 | private User user;
22 |
23 | public void setUser(User user) {
24 | this.user = user;
25 | }
26 |
27 | @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
28 | @JoinColumn(name = "keywordId")
29 | private Keyword keyword;
30 |
31 | public void setKeyword(Keyword keyword) {
32 | this.keyword = keyword;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/YoutubeAndNews.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.hermes.ithermes.domain.util.CategoryType;
5 | import com.hermes.ithermes.domain.util.ContentsProviderType;
6 | import com.hermes.ithermes.domain.util.ElasticSearchType;
7 | import jakarta.persistence.*;
8 | import lombok.AllArgsConstructor;
9 | import lombok.Builder;
10 | import lombok.Getter;
11 | import lombok.NoArgsConstructor;
12 |
13 | import java.time.LocalDateTime;
14 | import java.util.List;
15 |
16 | @Entity
17 | @Getter
18 | @Builder
19 | @NoArgsConstructor
20 | @AllArgsConstructor
21 | public class YoutubeAndNews extends BaseEntity implements CrawlingContents {
22 |
23 | @Version
24 | private Integer version;
25 |
26 | @Id
27 | @GeneratedValue(strategy = GenerationType.IDENTITY)
28 | private Long id;
29 |
30 | @Column(nullable = false)
31 | private String title;
32 |
33 | @Column(nullable = false, length = 1000)
34 | private String description;
35 |
36 | private String image;
37 |
38 | @Column(nullable = false)
39 | private String url;
40 |
41 | @Temporal(TemporalType.TIMESTAMP)
42 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
43 | @Column(nullable = false)
44 | private LocalDateTime contentsStartAt;
45 |
46 | @Column(nullable = false)
47 | private Long viewCount;
48 |
49 | @Column(nullable = false)
50 | private Boolean isDelete;
51 |
52 | @Enumerated(EnumType.STRING)
53 | @Column(nullable = false)
54 | private CategoryType category;
55 |
56 | @Enumerated(EnumType.STRING)
57 | @Column(nullable = false)
58 | private ContentsProviderType contentsProvider;
59 |
60 | @Enumerated(EnumType.STRING)
61 | private ElasticSearchType elasticSearchType;
62 |
63 | public void updateViewCount() {
64 | this.viewCount += +1L;
65 | }
66 |
67 | public void updateElasticSearchType() { this.elasticSearchType=ElasticSearchType.DONE; }
68 |
69 | @Override
70 | public String findTitle() {
71 | return title;
72 | }
73 |
74 | @Override
75 | public String findImage() {
76 | return image;
77 | }
78 |
79 | @Override
80 | public String findUrl() {
81 | return url;
82 | }
83 |
84 | @Override
85 | public CategoryType findCategoryType() {
86 | return category;
87 | }
88 |
89 | @Override
90 | public ContentsProviderType findContentsProvider() {
91 | return contentsProvider;
92 | }
93 |
94 | @Override
95 | public LocalDateTime findContentsTime() {
96 | return contentsStartAt;
97 | }
98 |
99 | @Override
100 | public String findDescription() {
101 | return description;
102 | }
103 |
104 | public boolean isContainRecommendKeywords(List keywordList){
105 | return keywordList.stream()
106 | .anyMatch(m->m.contains(title));
107 | }
108 |
109 | @Override
110 | public Long findViewCount() {
111 | return viewCount;
112 | }
113 |
114 | public static YoutubeAndNewsSearch convertESentity(YoutubeAndNews youtubeAndNews){
115 | return YoutubeAndNewsSearch.builder()
116 | .title(youtubeAndNews.getTitle())
117 | .description(youtubeAndNews.getDescription())
118 | .image(youtubeAndNews.getImage())
119 | .url(youtubeAndNews.getUrl())
120 | .contentsStartAt(youtubeAndNews.getContentsStartAt())
121 | .viewCount(youtubeAndNews.getViewCount())
122 | .isDelete(youtubeAndNews.getIsDelete())
123 | .category(youtubeAndNews.getCategory())
124 | .contentsProvider(youtubeAndNews.getContentsProvider())
125 | .build();
126 |
127 | }
128 |
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/entity/YoutubeAndNewsSearch.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.entity;
2 |
3 |
4 | import com.fasterxml.jackson.annotation.JsonFormat;
5 | import com.hermes.ithermes.domain.util.CategoryType;
6 | import com.hermes.ithermes.domain.util.ContentsProviderType;
7 | import jakarta.persistence.*;
8 | import lombok.*;
9 | import org.springframework.data.annotation.Id;
10 | import org.springframework.data.elasticsearch.annotations.DateFormat;
11 | import org.springframework.data.elasticsearch.annotations.Document;
12 | import org.springframework.data.elasticsearch.annotations.Field;
13 | import org.springframework.data.elasticsearch.annotations.FieldType;
14 |
15 | import java.time.LocalDateTime;
16 |
17 | @Getter
18 | @Builder
19 | @NoArgsConstructor
20 | @AllArgsConstructor
21 | @Document(indexName = "youtubeandnewssearch")
22 | public class YoutubeAndNewsSearch extends BaseEntity implements CrawlingContents {
23 |
24 | @Id
25 | private String id;
26 |
27 | @Column(nullable = false)
28 | private String title;
29 |
30 | @Column(nullable = false, length = 1000)
31 | private String description;
32 |
33 | private String image;
34 |
35 | @Column(nullable = false)
36 | private String url;
37 |
38 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
39 | @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss")
40 | private LocalDateTime contentsStartAt;
41 |
42 | @Column(nullable = false)
43 | private Long viewCount;
44 |
45 | @Column(nullable = false)
46 | private Boolean isDelete;
47 |
48 | @Enumerated(EnumType.STRING)
49 | @Column(nullable = false)
50 | private CategoryType category;
51 |
52 | @Enumerated(EnumType.STRING)
53 | @Column(nullable = false)
54 | private ContentsProviderType contentsProvider;
55 |
56 | @Override
57 | public String findTitle() {
58 | return title;
59 | }
60 |
61 | @Override
62 | public String findImage() {
63 | return image;
64 | }
65 |
66 | @Override
67 | public String findUrl() {
68 | return url;
69 | }
70 |
71 | @Override
72 | public CategoryType findCategoryType() {
73 | return category;
74 | }
75 |
76 | @Override
77 | public ContentsProviderType findContentsProvider() {
78 | return contentsProvider;
79 | }
80 |
81 | @Override
82 | public LocalDateTime findContentsTime() {
83 | return contentsStartAt;
84 | }
85 |
86 | @Override
87 | public String findDescription() {
88 | return description;
89 | }
90 |
91 | @Override
92 | public Long findViewCount() {
93 | return viewCount;
94 | }
95 |
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/EnumTypeFormatException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class EnumTypeFormatException extends RuntimeException{
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/ExpireTokenException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class ExpireTokenException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/JsonParseException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class JsonParseException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/NoAlarmDataException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class NoAlarmDataException extends RuntimeException{
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/NoCrawlingDataException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class NoCrawlingDataException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/NotExistsRequestParamException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class NotExistsRequestParamException extends RuntimeException {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/SameIdException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class SameIdException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/SameNicknameException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class SameNicknameException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/SameUserException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class SameUserException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/UnMatchedPasswordException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class UnMatchedPasswordException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/exception/WrongIdOrPasswordException.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.exception;
2 |
3 | public class WrongIdOrPasswordException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/factory/CrawlingContentsLastUrlFactory.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.factory;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContentsLastUrl;
4 | import com.hermes.ithermes.domain.entity.Job;
5 | import com.hermes.ithermes.domain.entity.YoutubeAndNews;
6 | import com.hermes.ithermes.domain.util.JobType;
7 | import com.hermes.ithermes.infrastructure.CrawlingContentsLastUrlRepository;
8 | import lombok.RequiredArgsConstructor;
9 | import org.springframework.stereotype.Component;
10 |
11 | import java.util.List;
12 |
13 | @Component
14 | @RequiredArgsConstructor
15 | public class CrawlingContentsLastUrlFactory {
16 | private final CrawlingContentsLastUrlRepository crawlingContentsLastUrlRepository;
17 |
18 | public List parseAllCrawlingContentsLastTitle() {
19 |
20 | List crawlingContentsLastUrlRepositoryAll = crawlingContentsLastUrlRepository.findAll();
21 | return crawlingContentsLastUrlRepositoryAll;
22 | }
23 |
24 | public CrawlingContentsLastUrl parseCrawlingContentsLastUrlToYoutubeAndNews(YoutubeAndNews youtubeAndNews) {
25 | return CrawlingContentsLastUrl.builder()
26 | .lastUrl(youtubeAndNews.getUrl())
27 | .contentsProvider(youtubeAndNews.getContentsProvider())
28 | .build();
29 | }
30 |
31 | public CrawlingContentsLastUrl parseCrawlingContentsLastUrlToJob(Job job, JobType jobType) {
32 | return CrawlingContentsLastUrl.builder()
33 | .lastUrl(job.getUrl())
34 | .grade(job.getGrade())
35 | .job(jobType)
36 | .contentsProvider(job.getContentsProvider())
37 | .build();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/factory/JobFactory.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.factory;
2 |
3 | import com.hermes.ithermes.domain.entity.Job;
4 | import com.hermes.ithermes.domain.util.ContentsProviderType;
5 | import com.hermes.ithermes.domain.util.GradeType;
6 | import com.hermes.ithermes.domain.util.JobType;
7 | import com.hermes.ithermes.infrastructure.JobRepository;
8 | import com.hermes.ithermes.presentation.dto.job.JobCrawlingDto;
9 | import com.hermes.ithermes.presentation.dto.job.JobInsertRequestDto;
10 | import lombok.RequiredArgsConstructor;
11 | import org.springframework.stereotype.Component;
12 |
13 | import java.time.LocalDateTime;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | @Component
18 | @RequiredArgsConstructor
19 | public class JobFactory {
20 | private final JobRepository jobRepository;
21 |
22 | public List insertJob(JobInsertRequestDto jobInsertRequestDto) {
23 | List jobList = new ArrayList<>();
24 | List jobCrawlingDtoList = jobInsertRequestDto.getJobCrawlingDtoList();
25 | ContentsProviderType contentsProvider = jobInsertRequestDto.getContentsProvider();
26 | GradeType grade = jobInsertRequestDto.getGrade();
27 | JobType jobType = jobInsertRequestDto.getJob();
28 | jobCrawlingDtoList.stream().forEach(v -> {
29 | String company = v.getCompany();
30 | String title = v.getTitle();
31 | String url = v.getUrl();
32 | String location = v.getLocation();
33 | String[] startDateArray = v.getStartDate().split("-");
34 | String[] endDateArray = v.getStartDate().split("-");
35 | LocalDateTime startDate = LocalDateTime.of(
36 | Integer.parseInt(startDateArray[0]),
37 | Integer.parseInt(startDateArray[1]),
38 | Integer.parseInt(startDateArray[2]),
39 | Integer.parseInt(startDateArray[3]),
40 | Integer.parseInt(startDateArray[4]),
41 | Integer.parseInt(startDateArray[5]));
42 |
43 | LocalDateTime endDate = LocalDateTime.of(
44 | Integer.parseInt(endDateArray[0]),
45 | Integer.parseInt(endDateArray[1]),
46 | Integer.parseInt(endDateArray[2]),
47 | Integer.parseInt(endDateArray[3]),
48 | Integer.parseInt(endDateArray[4]),
49 | Integer.parseInt(endDateArray[5]));
50 |
51 | Job job = Job
52 | .builder()
53 | .company(company)
54 | .title(title)
55 | .url(url)
56 | .location(location)
57 | .grade(grade)
58 | .contentsStartAt(startDate)
59 | .contentsEndAt(endDate)
60 | .isDelete(false)
61 | .viewCount(0L)
62 | .contentsProvider(contentsProvider)
63 | .jobType(jobType)
64 | .build();
65 |
66 | jobList.add(job);
67 | });
68 | return jobList;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/factory/KeywordFactory.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.factory;
2 |
3 | import com.hermes.ithermes.domain.entity.Keyword;
4 | import lombok.Builder;
5 | import org.springframework.stereotype.Component;
6 |
7 | @Builder
8 | @Component
9 | public class KeywordFactory {
10 | public Keyword parseKeywordNameToKeyword(String keywordName) {
11 | Keyword keyword = Keyword.builder().name(keywordName).build();
12 | return keyword;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/factory/RedisFactory.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.factory;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import org.springframework.data.redis.core.RedisTemplate;
5 | import org.springframework.stereotype.Component;
6 |
7 | @Component
8 | @RequiredArgsConstructor
9 | public class RedisFactory {
10 |
11 | private final RedisTemplate redisTemplate;
12 |
13 | public String setRedisRefreshToken(String key, String value) {
14 | redisTemplate.opsForValue().set(key, value);
15 | return value;
16 | }
17 |
18 | public String getRedisRefreshToken(String key) {
19 | return redisTemplate.opsForValue().get(key);
20 | }
21 |
22 | public void deleteRedisRefreshToken(String key) {
23 | redisTemplate.delete(key);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/factory/SubscribeFactory.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.factory;
2 |
3 | import com.hermes.ithermes.domain.entity.Subscribe;
4 | import com.hermes.ithermes.domain.entity.User;
5 | import com.hermes.ithermes.domain.exception.EnumTypeFormatException;
6 | import com.hermes.ithermes.domain.exception.WrongIdOrPasswordException;
7 | import com.hermes.ithermes.domain.util.ActiveType;
8 | import com.hermes.ithermes.domain.util.CategoryType;
9 | import com.hermes.ithermes.domain.util.ContentsProviderType;
10 | import com.hermes.ithermes.infrastructure.SubscribeRepository;
11 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeContentsDto;
12 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeFindSubscribeRequestDto;
13 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribePutSubscribeRequestDto;
14 | import lombok.Builder;
15 | import lombok.RequiredArgsConstructor;
16 | import org.springframework.stereotype.Component;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 | import java.util.Optional;
21 | import java.util.stream.Collectors;
22 |
23 | @Builder
24 | @Component
25 | @RequiredArgsConstructor
26 | public class SubscribeFactory {
27 | private final SubscribeRepository subscribeRepository;
28 | private final UserFactory userFactory;
29 |
30 | public List parsePutSubscribeDtoToSubscribes(SubscribePutSubscribeRequestDto subscribePutSubscribeRequestDto) {
31 | List subscribes = new ArrayList<>();
32 | String loginId = subscribePutSubscribeRequestDto.getId();
33 | User user = userFactory.findLoginId(loginId).orElseThrow(() -> new WrongIdOrPasswordException());
34 | ArrayList subscribeContentsList = subscribePutSubscribeRequestDto.getSubscribeContentsList();
35 | boolean isEdit = existsByUserId(user.getId());
36 |
37 | subscribeContentsList.stream().forEach(v -> {
38 | ContentsProviderType contentsProviderType = ContentsProviderType.valueOf(v.getContentsProvider());
39 | CategoryType categoryType = CategoryType.findByContentsProviderType(contentsProviderType);
40 | ActiveType activeType = ActiveType.valueOf(v.getIsActive());
41 |
42 | Subscribe subscribe = CategoryType.parseSubscribe(user, categoryType, contentsProviderType, activeType);
43 | if (isEdit) {
44 | Subscribe editSubscribe = subscribeRepository.findByContentsProvider(ContentsProviderType.valueOf(v.getContentsProvider())).orElseThrow(() -> new EnumTypeFormatException());
45 | editSubscribe.changeUpdateAt(ActiveType.valueOf(v.getIsActive()));
46 | } else {
47 | subscribes.add(subscribe);
48 | }
49 |
50 | });
51 | return subscribes;
52 | }
53 |
54 | public List parseFindSubscribeDtoToSubscribes(SubscribeFindSubscribeRequestDto subscribeFindSubscribeRequestDto) {
55 | String loginId = subscribeFindSubscribeRequestDto.getId();
56 | User user = userFactory.findLoginId(loginId).orElseThrow(() -> new WrongIdOrPasswordException());
57 | Long userId = user.getId();
58 | return findSubscribeByUserId(userId).orElseThrow(null);
59 | }
60 |
61 | public static List findActiveContentsProviderType(List subscribes) {
62 | return subscribes.stream().map(v -> new SubscribeContentsDto(v.getContentsProvider().getTitle(), v.getIsActive().getTitle())).collect(Collectors.toList());
63 | }
64 |
65 | public Optional> findSubscribeByUserId(Long userId) {
66 | return subscribeRepository.findByUserId(userId);
67 | }
68 |
69 | public boolean existsByUserId(Long userId) {
70 | return subscribeRepository.existsByUserId(userId);
71 | }
72 | }
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/factory/UrlRecordFactory.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.factory;
2 |
3 | import com.hermes.ithermes.domain.entity.UrlRecord;
4 | import com.hermes.ithermes.infrastructure.UrlRecordRepository;
5 | import com.hermes.ithermes.presentation.dto.urlrecord.UrlRecordPutViewCountRequestDto;
6 | import lombok.RequiredArgsConstructor;
7 | import org.springframework.stereotype.Component;
8 |
9 | @Component
10 | @RequiredArgsConstructor
11 | public class UrlRecordFactory {
12 | private final UrlRecordRepository urlRecordRepository;
13 |
14 | public UrlRecord parseUrlRecord(UrlRecordPutViewCountRequestDto urlRecordPutViewCountRequestDto, String ipAddress) {
15 | UrlRecord urlRecord = UrlRecord
16 | .builder()
17 | .url(urlRecordPutViewCountRequestDto.getUrl())
18 | .clientIpAddress(ipAddress)
19 | .build();
20 |
21 | return urlRecord;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/factory/UserFactory.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.factory;
2 |
3 | import com.hermes.ithermes.domain.entity.User;
4 | import com.hermes.ithermes.infrastructure.UserRepository;
5 | import com.hermes.ithermes.presentation.dto.user.UserCreateUserRequestDto;
6 | import com.hermes.ithermes.presentation.dto.user.UserFindUserListResponseDto;
7 | import lombok.Builder;
8 | import lombok.RequiredArgsConstructor;
9 | import org.springframework.stereotype.Component;
10 |
11 | import java.util.Optional;
12 |
13 | @Builder
14 | @Component
15 | @RequiredArgsConstructor
16 | public class UserFactory {
17 | private final UserRepository userRepository;
18 |
19 | public User parseLoginRequestDtoToUser(UserCreateUserRequestDto userLoginRequestDto) {
20 | User user = User.builder()
21 | .loginId(userLoginRequestDto.getId())
22 | .password(userLoginRequestDto.getPassword())
23 | .nickname(userLoginRequestDto.getNickname())
24 | .job(userLoginRequestDto.getJob())
25 | .yearOfExperience(Integer.parseInt(userLoginRequestDto.getYearOfExperience()))
26 | .isDelete(false)
27 | .build();
28 | return user;
29 | }
30 |
31 | public Optional findLoginId(String userId) {
32 | return userRepository.findByLoginId(userId);
33 | }
34 |
35 | public boolean existsByLoginId(String userId) {
36 | return userRepository.existsByLoginId(userId);
37 | }
38 |
39 | public boolean existsByNickname(String nickname) {
40 | return userRepository.existsByNickname(nickname);
41 | }
42 |
43 | public static UserFindUserListResponseDto parseUserToRequestUserDto(User user) {
44 |
45 | return UserFindUserListResponseDto.builder()
46 | .loginId(user.getLoginId())
47 | .nickname(user.getNickname())
48 | .jobType(user.getJob().name())
49 | .yearOfExperience(user.getYearOfExperience())
50 | .subscribeList(SubscribeFactory.findActiveContentsProviderType(user.getSubscribe()))
51 | .build();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/factory/UserKeywordRegistryFactory.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.factory;
2 |
3 | import com.hermes.ithermes.domain.entity.Keyword;
4 | import com.hermes.ithermes.domain.entity.User;
5 | import com.hermes.ithermes.domain.entity.UserKeywordRegistry;
6 | import org.springframework.stereotype.Component;
7 |
8 | @Component
9 | public class UserKeywordRegistryFactory {
10 |
11 | public UserKeywordRegistry parseUserAndKeyword(User user, Keyword keyword) {
12 | UserKeywordRegistry userKeywordRegistry = UserKeywordRegistry.builder()
13 | .user(user)
14 | .keyword(keyword)
15 | .build();
16 | return userKeywordRegistry;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/factory/YoutubeAndNewsFactory.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.factory;
2 |
3 | import com.hermes.ithermes.domain.entity.YoutubeAndNews;
4 | import com.hermes.ithermes.domain.util.CategoryType;
5 | import com.hermes.ithermes.domain.util.ContentsProviderType;
6 | import com.hermes.ithermes.infrastructure.YoutubeAndNewsRepository;
7 | import com.hermes.ithermes.presentation.dto.youtubeandnews.YoutubeAndNewsCrawlingDto;
8 | import com.hermes.ithermes.presentation.dto.youtubeandnews.YoutubeAndNewsInsertDto;
9 | import lombok.RequiredArgsConstructor;
10 | import org.springframework.stereotype.Component;
11 |
12 | import java.time.LocalDateTime;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | @Component
17 | @RequiredArgsConstructor
18 | public class YoutubeAndNewsFactory {
19 | private final YoutubeAndNewsRepository youtubeAndNewsRepository;
20 |
21 | public List parseYoutubeAndNews(YoutubeAndNewsInsertDto youtubeAndNewsCrawlingDtoList) {
22 | List youtubeAndNewsList = new ArrayList<>();
23 | ArrayList crawlingList = youtubeAndNewsCrawlingDtoList.getYoutubeAndNewsCrawlingDtoList();
24 | CategoryType categoryType = youtubeAndNewsCrawlingDtoList.getCategory();
25 | ContentsProviderType contentsProvider = youtubeAndNewsCrawlingDtoList.getContentsProvider();
26 | crawlingList.stream().forEach(v -> {
27 | String title = v.getTitle();
28 | String description = v.getDescription();
29 | String thumbnail = v.getThumbnail();
30 | String url = v.getUrl();
31 | String[] dateArray = v.getDate().split("-");
32 | LocalDateTime date = LocalDateTime.of(
33 | Integer.parseInt(dateArray[0]),
34 | Integer.parseInt(dateArray[1]),
35 | Integer.parseInt(dateArray[2]),
36 | Integer.parseInt(dateArray[3]),
37 | Integer.parseInt(dateArray[4]),
38 | Integer.parseInt(dateArray[5]));
39 |
40 | YoutubeAndNews youtubeAndNews = YoutubeAndNews
41 | .builder()
42 | .description(description)
43 | .title(title)
44 | .image(thumbnail)
45 | .url(url)
46 | .contentsStartAt(date)
47 | .isDelete(false)
48 | .viewCount(0L)
49 | .category(categoryType)
50 | .contentsProvider(contentsProvider)
51 | .build();
52 | youtubeAndNewsList.add(youtubeAndNews);
53 | });
54 | return youtubeAndNewsList;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/util/ActiveType.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.util;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | public enum ActiveType {
7 | ACTIVE("ACTIVE"),
8 | NOT_ACTIVE("NOT_ACTIVE");
9 |
10 | private String title;
11 |
12 | ActiveType(String title) {
13 | this.title = title;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/util/CategoryType.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.util;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import com.hermes.ithermes.domain.entity.Subscribe;
5 | import com.hermes.ithermes.domain.entity.User;
6 | import com.hermes.ithermes.domain.exception.EnumTypeFormatException;
7 | import lombok.Getter;
8 |
9 | import java.util.Arrays;
10 | import java.util.List;
11 |
12 | @Getter
13 | public enum CategoryType {
14 | JOB("JOB", Arrays.asList(ContentsProviderType.SARAMIN, ContentsProviderType.WANTED)),
15 | NEWS("NEWS", Arrays.asList(ContentsProviderType.CODING_WORLD, ContentsProviderType.YOZM)),
16 | YOUTUBE("YOUTUBE", Arrays.asList(
17 | ContentsProviderType.NOMAD_CODERS, ContentsProviderType.DREAM_CODING,
18 | ContentsProviderType.WHITESHIP,ContentsProviderType.FI,ContentsProviderType.LINE_DEVELOP,
19 | ContentsProviderType.DEVELOP_FOOT, ContentsProviderType.NULLNULL_DEVELOP, ContentsProviderType.DONGBINNA,
20 | ContentsProviderType.POPE, ContentsProviderType.WOOWA_COURSE
21 | )),
22 | YOUTUBE_AND_NEWS("YOUTUBE_AND_NEWS",Arrays.asList(ContentsProviderType.NOMAD_CODERS,ContentsProviderType.DREAM_CODING,
23 | ContentsProviderType.CODING_WORLD,ContentsProviderType.YOZM,
24 | ContentsProviderType.WHITESHIP,ContentsProviderType.FI,ContentsProviderType.LINE_DEVELOP,
25 | ContentsProviderType.DEVELOP_FOOT, ContentsProviderType.NULLNULL_DEVELOP, ContentsProviderType.DONGBINNA,
26 | ContentsProviderType.POPE, ContentsProviderType.WOOWA_COURSE
27 | ));
28 |
29 | private String title;
30 | private List contentsProviderTypes;
31 |
32 | CategoryType(String title, List contentsProviderTypes) {
33 | this.title = title;
34 | this.contentsProviderTypes = contentsProviderTypes;
35 | }
36 |
37 | public static CategoryType findByContentsProviderType(ContentsProviderType contentsProviderType) {
38 | return Arrays.stream(CategoryType.values())
39 | .filter(categoryType -> categoryType.matchContentsProviderType(contentsProviderType))
40 | .findAny()
41 | .orElseThrow(() -> new EnumTypeFormatException());
42 | }
43 |
44 | public boolean matchContentsProviderType(ContentsProviderType contentsProviderType) {
45 | return contentsProviderTypes.stream()
46 | .anyMatch(contentsProviderTypeList -> contentsProviderTypeList.equals(contentsProviderType));
47 | }
48 |
49 | public static Subscribe parseSubscribe(User user, CategoryType categoryType, ContentsProviderType contentsProviderType, ActiveType activeType) {
50 | return Subscribe.builder()
51 | .user(user)
52 | .category(categoryType)
53 | .contentsProvider(contentsProviderType)
54 | .isActive(activeType)
55 | .build();
56 | }
57 |
58 | @JsonCreator
59 | public static CategoryType fromValue(String category) {
60 | return CategoryType.valueOf(category.toUpperCase());
61 | }
62 |
63 | public static boolean isContainCategoryType(String title){
64 | for(CategoryType c: CategoryType.values()){
65 | if(c.getTitle().equals(title)){
66 | return true;
67 | }
68 | }
69 | return false;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/util/ContentsProviderType.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.util;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import lombok.Getter;
5 |
6 | @Getter
7 | public enum ContentsProviderType {
8 | SARAMIN("SARAMIN"),
9 | WANTED("WANTED"),
10 | CODING_WORLD("CODING_WORLD"),
11 | YOZM("YOZM"),
12 | NOMAD_CODERS("NOMAD_CODERS"),
13 | DREAM_CODING("DREAM_CODING"),
14 | WHITESHIP("WHITESHIP"),
15 | FI("FI"),
16 | LINE_DEVELOP("LINE_DEVELOP"),
17 | DEVELOP_FOOT("DEVELOP_FOOT"),
18 | NULLNULL_DEVELOP("NULLNULL_DEVELOP"),
19 | DONGBINNA("DONGBINNA"),
20 | POPE("POPE"),
21 | WOOWA_COURSE("WOOWA_COURSE");
22 |
23 | private String title;
24 |
25 | ContentsProviderType(String title) {
26 | this.title = title;
27 | }
28 |
29 | @JsonCreator
30 | public static ContentsProviderType fromValue(String contentsProvider) {
31 | return ContentsProviderType.valueOf(contentsProvider.toUpperCase());
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/util/ElasticSearchType.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.util;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import lombok.Getter;
5 |
6 | @Getter
7 | public enum ElasticSearchType {
8 | READY("READY"),
9 | DONE("DONE");
10 |
11 | private String text;
12 |
13 | ElasticSearchType(String text) {
14 | this.text = text;
15 | }
16 |
17 | @JsonCreator
18 | public static ElasticSearchType fromValue(String text) {
19 | return ElasticSearchType.valueOf(text);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/util/GradeType.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.util;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 |
5 | public enum GradeType {
6 | BEGINNER("BEGINNER", 0, 0),
7 | JUNIOR("JUNIOR", 1, 4),
8 | INTERMEDIATE("INTERMEDIATE", 5, 9),
9 | SENIOR("SENIOR", 10, 30);
10 |
11 | private String name;
12 | private int minExperience;
13 | private int maxExperience;
14 |
15 | GradeType(String name, int minExperience, int maxExperience) {
16 | this.name = name;
17 | this.minExperience = minExperience;
18 | this.maxExperience = maxExperience;
19 | }
20 |
21 | public static GradeType checkGradleType(int experience) {
22 | if (experience < BEGINNER.minExperience) return GradeType.BEGINNER;
23 | else if (experience > 0 && experience <= 4) return GradeType.JUNIOR;
24 | else if (experience > 4 && experience < 10) return GradeType.INTERMEDIATE;
25 | else return GradeType.SENIOR;
26 | }
27 |
28 | @JsonCreator
29 | public static JobType fromValue(String grade) {
30 | return JobType.valueOf(grade.toUpperCase());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/util/JobType.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.util;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import lombok.Getter;
5 |
6 | import java.util.Arrays;
7 | import java.util.List;
8 |
9 | @Getter
10 | public enum JobType {
11 | FRONT("FRONT", Arrays.asList("UIUX","React","Vue","HTML","CSS")),
12 | BACKEND("BACKEND",Arrays.asList("데이터베이스","API")),
13 | MOBILE("MOBILE",Arrays.asList("iOS","안드로이드"));
14 |
15 | private String title;
16 | private List keywords;
17 |
18 | JobType(String title, List keywords) {
19 | this.title = title;
20 | this.keywords = keywords;
21 | }
22 |
23 | @JsonCreator
24 | public static JobType fromValue(String job) {
25 | return JobType.valueOf(job.toUpperCase());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/util/OrderType.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.util;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | public enum OrderType {
7 |
8 | ID("ID","createdAt"),
9 | RECENT("RECENT","contentsStartAt"),
10 | POPULAR("POPULAR","viewCount");
11 |
12 | private String name;
13 | private String orderQuery;
14 |
15 | OrderType(String name, String orderQuery) {
16 | this.name = name;
17 | this.orderQuery = orderQuery;
18 | }
19 |
20 | public static boolean isContainOrderType(String type){
21 | for(OrderType o: OrderType.values()){
22 | if(o.getName().equals(type)){
23 | return true;
24 | }
25 | }
26 | return false;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/domain/util/RecommendKeywordType.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.domain.util;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | public enum RecommendKeywordType {
7 |
8 | MachineLearning("머신러닝"),
9 | BigData("빅데이터"),
10 | Security("보안"),
11 | OpenSource("오픈소스"),
12 | Cloud("클라우드"),
13 | Framework("프레임워크");
14 |
15 | private String name;
16 |
17 | RecommendKeywordType(String name) {
18 | this.name = name;
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/CrawlingContentsLastUrlRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContentsLastUrl;
4 | import com.hermes.ithermes.domain.util.ContentsProviderType;
5 | import com.hermes.ithermes.domain.util.GradeType;
6 | import com.hermes.ithermes.domain.util.JobType;
7 | import org.springframework.data.jpa.repository.JpaRepository;
8 | import org.springframework.data.repository.query.Param;
9 | import org.springframework.stereotype.Repository;
10 |
11 | import java.util.List;
12 | import java.util.Optional;
13 |
14 | @Repository
15 | public interface CrawlingContentsLastUrlRepository extends JpaRepository {
16 | List findAll();
17 | Optional findByContentsProvider(@Param("contentsProvider")ContentsProviderType contentsProvider);
18 | Optional findByContentsProviderAndGradeAndJob(@Param("contentsProvider")ContentsProviderType contentsProvider, @Param("grade")GradeType grade, @Param("job") JobType job);
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/JobRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure;
2 |
3 | import java.util.List;
4 |
5 | import com.hermes.ithermes.domain.entity.CrawlingContents;
6 | import com.hermes.ithermes.domain.entity.Job;
7 | import com.hermes.ithermes.domain.util.ContentsProviderType;
8 | import com.hermes.ithermes.domain.util.ElasticSearchType;
9 | import com.hermes.ithermes.domain.util.GradeType;
10 | import com.hermes.ithermes.domain.util.JobType;
11 | import org.springframework.data.domain.Page;
12 | import org.springframework.data.domain.Pageable;
13 | import org.springframework.data.jpa.repository.JpaRepository;
14 | import org.springframework.data.jpa.repository.Query;
15 | import org.springframework.data.repository.query.Param;
16 | import org.springframework.stereotype.Repository;
17 |
18 | import java.util.Optional;
19 |
20 | @Repository
21 | public interface JobRepository extends JpaRepository {
22 |
23 | Page findJobBy(Pageable pageable);
24 | List findByTitleContaining(String searchKeyword);
25 | @Query("select jn from Job jn where jn.id<(select innerjn.id from Job innerjn where innerjn.url=:url and innerjn.contentsProvider=:contentsProviderType and innerjn.grade=:GradeType and innerjn.jobType=:JobType) and jn.contentsProvider=:contentsProviderType and jn.grade=:GradeType and jn.jobType=:JobType")
26 | List findJobByUrlGreater(@Param("url") String url, @Param("contentsProviderType") ContentsProviderType contentsProvider, @Param("GradeType") GradeType gradeType, @Param("JobType")JobType jobType);
27 | List findJobByContentsProvider(ContentsProviderType contentsProviderType);
28 | Optional> findByUrl(@Param("url") String url);
29 | Long countBy();
30 | List findByElasticSearchType(ElasticSearchType elasticSearchType);
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/KeywordRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure;
2 |
3 | import com.hermes.ithermes.domain.entity.Keyword;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface KeywordRepository extends JpaRepository {
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/SubscribeRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure;
2 |
3 | import com.hermes.ithermes.domain.entity.Subscribe;
4 | import com.hermes.ithermes.domain.util.ActiveType;
5 | import com.hermes.ithermes.domain.util.CategoryType;
6 | import com.hermes.ithermes.domain.util.ContentsProviderType;
7 | import org.springframework.data.jpa.repository.JpaRepository;
8 | import org.springframework.data.jpa.repository.Query;
9 | import org.springframework.data.repository.query.Param;
10 |
11 | import java.util.List;
12 | import java.util.Optional;
13 |
14 | public interface SubscribeRepository extends JpaRepository {
15 | Optional> findByUserId(@Param("userId") Long userId);
16 |
17 | @Query("select s.contentsProvider from Subscribe s where s.isActive = :active and s.user.id = :userId and s.category = :category")
18 | List findContentsProvider(@Param("active") ActiveType active, @Param("userId") Long userId, @Param("category") CategoryType categoryType);
19 |
20 | boolean existsByUserId(@Param("userId") Long userId);
21 |
22 | Optional findByContentsProvider(@Param("contentsProvider") ContentsProviderType contentsProvider);
23 |
24 | List findByUserIdAndCategoryAndIsActive(@Param("userId") Long userId, @Param("category") CategoryType categoryType, @Param("active") ActiveType active);
25 |
26 | Subscribe findByUserIdAndContentsProvider(Long userId, ContentsProviderType contentsProviderType);
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/UrlRecordRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure;
2 |
3 | import com.hermes.ithermes.domain.entity.UrlRecord;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.repository.query.Param;
6 | import org.springframework.stereotype.Repository;
7 |
8 | @Repository
9 | public interface UrlRecordRepository extends JpaRepository {
10 | boolean existsByUrlAndClientIpAddress(@Param("url") String url, @Param("clientIpAddress") String clientIpAddress);
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/UserKeywordRegistryRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure;
2 |
3 | import com.hermes.ithermes.domain.entity.UserKeywordRegistry;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | public interface UserKeywordRegistryRepository extends JpaRepository {
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/UserRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure;
2 |
3 | import com.hermes.ithermes.domain.entity.User;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.data.jpa.repository.Query;
6 | import org.springframework.data.repository.query.Param;
7 | import org.springframework.stereotype.Repository;
8 |
9 | import java.util.List;
10 | import java.util.Optional;
11 |
12 | @Repository
13 | public interface UserRepository extends JpaRepository {
14 |
15 | @Query("SELECT u FROM User u JOIN FETCH u.subscribe")
16 | List findUserAndSubscribe();
17 |
18 | Optional findByLoginId(@Param("loginId") String loginId);
19 |
20 | boolean existsByNickname(@Param("nickname") String nickname);
21 |
22 | boolean existsByLoginId(@Param("loginId") String loginId);
23 |
24 | Boolean existsUserByNicknameAndTelegramId(String nickname,String telegramId);
25 |
26 | Boolean existsUserByNickname(String nickname);
27 |
28 | @Query("SELECT u.id FROM User u where u.telegramId is not null and u.isDelete=false")
29 | List findUserId();
30 |
31 | @Query("SELECT u.telegramId FROM User u where u.id=:id")
32 | String findTelegramIdByUserId(@Param("id") Long id);
33 |
34 | User findByNickname(String nickname);
35 |
36 | User findUsersById(Long id);
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/YoutubeAndNewsRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContents;
4 | import com.hermes.ithermes.domain.entity.YoutubeAndNews;
5 | import com.hermes.ithermes.domain.util.CategoryType;
6 | import com.hermes.ithermes.domain.util.ContentsProviderType;
7 | import com.hermes.ithermes.domain.util.ElasticSearchType;
8 | import org.springframework.data.domain.Page;
9 | import org.springframework.data.domain.Pageable;
10 | import org.springframework.data.jpa.repository.JpaRepository;
11 | import org.springframework.data.jpa.repository.Query;
12 | import org.springframework.data.repository.query.Param;
13 | import org.springframework.stereotype.Repository;
14 |
15 | import java.util.List;
16 | import java.util.Optional;
17 |
18 | @Repository
19 | public interface YoutubeAndNewsRepository extends JpaRepository {
20 |
21 | Page findYoutubeAndNewsBy(Pageable pageable);
22 | Page findYoutubeAndNewsByCategory(Pageable pageable, CategoryType type);
23 | List findByTitleContainingAndCategory(String searchKeyword,CategoryType type);
24 | @Query("select yn from YoutubeAndNews yn where yn.id<(select inneryn.id from YoutubeAndNews inneryn where inneryn.url=:url and inneryn.contentsProvider=:contentsProviderType) and yn.contentsProvider=:contentsProviderType")
25 | List findYoutubeAndNewsByUrlGreater(@Param("url") String url,@Param("contentsProviderType") ContentsProviderType contentsProviderType);
26 | List findYoutubeAndNewsByContentsProvider(ContentsProviderType contentsProvider);
27 | Optional> findByUrl(@Param("url") String url);
28 | Long countYoutubeAndNewsByCategory(@Param("category") CategoryType category);
29 | List findByElasticSearchType(ElasticSearchType elasticSearchType);
30 |
31 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/elastic/AlarmSearchRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure.elastic;
2 |
3 | import com.hermes.ithermes.domain.entity.AlarmSearch;
4 | import com.hermes.ithermes.domain.util.CategoryType;
5 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
6 | import org.springframework.stereotype.Repository;
7 |
8 | import java.util.List;
9 | import java.util.Optional;
10 |
11 | @Repository
12 | public interface AlarmSearchRepository extends ElasticsearchRepository {
13 |
14 | Optional> findByCategory(CategoryType categoryType);
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/elastic/JobSearchRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure.elastic;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContents;
4 | import com.hermes.ithermes.domain.entity.JobSearch;
5 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
6 | import org.springframework.stereotype.Repository;
7 |
8 | import java.util.List;
9 |
10 | @Repository
11 | public interface JobSearchRepository extends ElasticsearchRepository {
12 | List findByTitleContaining(String title);
13 | void save(JobSearch jobSearch);
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/infrastructure/elastic/YoutubeAndNewsSearchRepository.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.infrastructure.elastic;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContents;
4 | import com.hermes.ithermes.domain.entity.YoutubeAndNewsSearch;
5 | import com.hermes.ithermes.domain.util.CategoryType;
6 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
7 | import org.springframework.stereotype.Repository;
8 |
9 | import java.util.List;
10 |
11 | @Repository
12 | public interface YoutubeAndNewsSearchRepository extends ElasticsearchRepository {
13 | List findByTitleContainingAndCategory(String title, CategoryType categoryType);
14 | void save(YoutubeAndNewsSearch youtubeAndNewsSearch);
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/GlobalExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation;
2 |
3 | import com.hermes.ithermes.domain.exception.*;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.http.ResponseEntity;
6 | import org.springframework.web.bind.MethodArgumentNotValidException;
7 | import org.springframework.web.bind.annotation.ExceptionHandler;
8 | import org.springframework.web.bind.annotation.RestControllerAdvice;
9 | @RestControllerAdvice
10 | public class GlobalExceptionHandler {
11 |
12 | @ExceptionHandler(NotExistsRequestParamException.class)
13 | public ResponseEntity NotExistsRequestValue(){
14 | return new ResponseEntity<>("잘못된 요청 파라미터 값입니다.", HttpStatus.BAD_REQUEST);
15 | }
16 |
17 | @ExceptionHandler(SameIdException.class)
18 | public ResponseEntity handleLSameIdException() {
19 | return new ResponseEntity<>("이미 존재하는 아이디", HttpStatus.BAD_REQUEST);
20 | }
21 |
22 | @ExceptionHandler(SameNicknameException.class)
23 | public ResponseEntity handleLSameNicknameException() {
24 | return new ResponseEntity<>("동일한 닉네임 회원 존재", HttpStatus.BAD_REQUEST);
25 | }
26 |
27 | @ExceptionHandler(UnMatchedPasswordException.class)
28 | public ResponseEntity handleUnMatchedPasswordException() {
29 | return new ResponseEntity<>("비밀번호와 비밀번호 확인 데이터 불일치", HttpStatus.BAD_REQUEST);
30 | }
31 |
32 | @ExceptionHandler(WrongIdOrPasswordException.class)
33 | public ResponseEntity handleWrongIdOrPasswordException() {
34 | return new ResponseEntity<>("아이디 또는 비밀번호 불일치", HttpStatus.BAD_REQUEST);
35 | }
36 |
37 | @ExceptionHandler(SameUserException.class)
38 | public ResponseEntity handleSameUserException() {
39 | return new ResponseEntity<>("이미 존재하는 회원", HttpStatus.BAD_REQUEST);
40 | }
41 |
42 | @ExceptionHandler(EnumTypeFormatException.class)
43 | public ResponseEntity enumTypeFormatException() {
44 | return new ResponseEntity<>("서버에 존재하지 않는 유효하지 않는 데이터", HttpStatus.BAD_REQUEST);
45 | }
46 | @ExceptionHandler(value = MethodArgumentNotValidException.class)
47 | public ResponseEntity methodArgumentNotValidException(MethodArgumentNotValidException e){
48 | return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
49 | }
50 |
51 | @ExceptionHandler(value = NoCrawlingDataException.class)
52 | public ResponseEntity noCrawlingDataException(){
53 | return new ResponseEntity<>("크롤링 데이터가 존재하지 않음", HttpStatus.BAD_REQUEST);
54 | }
55 |
56 | @ExceptionHandler(value = JsonParseException.class)
57 | public ResponseEntity jsonParseException(){
58 | return new ResponseEntity<>("JSON 데이터 파싱 중 오류 발생", HttpStatus.BAD_REQUEST);
59 | }
60 |
61 | @ExceptionHandler(value = ExpireTokenException.class)
62 | public ResponseEntity expireRefreshTokenException(){
63 | return new ResponseEntity<>("인증 토큰 만료 혹은 유효하지 않음", HttpStatus.UNAUTHORIZED);
64 | }
65 |
66 | @ExceptionHandler(value = NoAlarmDataException.class)
67 | public ResponseEntity noAlarmDataException(){
68 | return new ResponseEntity<>("알림데이터가 존재하지 않습니다,", HttpStatus.NOT_FOUND);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/aop/ControllerLogAop.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.aop;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.aspectj.lang.ProceedingJoinPoint;
5 | import org.aspectj.lang.annotation.Around;
6 | import org.aspectj.lang.annotation.Aspect;
7 | import org.springframework.stereotype.Component;
8 | import org.springframework.util.StopWatch;
9 |
10 | @Aspect
11 | @Component
12 | @Slf4j
13 | public class ControllerLogAop {
14 | @Around("within(com.hermes.ithermes.presentation.controller.*)")
15 | public Object checkLog(ProceedingJoinPoint joinPoint) throws Throwable {
16 | StopWatch stopWatch = new StopWatch();
17 | try {
18 | stopWatch.start();
19 | return joinPoint.proceed();
20 | } finally {
21 | stopWatch.stop();
22 | String className = joinPoint.getTarget().getClass().getName();
23 | String methodName = joinPoint.getSignature().getName() + "()";
24 | log.info("className : {} | methodName : {} server | transaction Processing Time : {} ms", className, methodName, stopWatch.getLastTaskTimeMillis());
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/aop/ServiceLogAop.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.aop;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.aspectj.lang.ProceedingJoinPoint;
5 | import org.aspectj.lang.annotation.Around;
6 | import org.aspectj.lang.annotation.Aspect;
7 | import org.springframework.stereotype.Component;
8 | import org.springframework.util.StopWatch;
9 |
10 | @Aspect
11 | @Component
12 | @Slf4j
13 | public class ServiceLogAop {
14 | @Around("within(com.hermes.ithermes.application.*)")
15 | public Object checkLog(ProceedingJoinPoint joinPoint) throws Throwable {
16 | StopWatch stopWatch = new StopWatch();
17 | try {
18 | stopWatch.start();
19 | return joinPoint.proceed();
20 | } finally {
21 | stopWatch.stop();
22 | String className = joinPoint.getTarget().getClass().getName();
23 | String methodName = joinPoint.getSignature().getName() + "()";
24 | log.info("className : {} | methodName : {} server | transaction Processing Time : {} ms", className, methodName, stopWatch.getLastTaskTimeMillis());
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/config/AbstractElasticsearchConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.config;
2 |
3 | import org.elasticsearch.client.RestHighLevelClient;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
6 | import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
7 | import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
8 | import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
9 |
10 | public abstract class AbstractElasticsearchConfiguration extends ElasticsearchConfigurationSupport {
11 |
12 | @Bean
13 | public abstract RestHighLevelClient elasticsearchClient();
14 |
15 | @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
16 | public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter,
17 | RestHighLevelClient elasticsearchClient) {
18 |
19 | ElasticsearchRestTemplate template = new ElasticsearchRestTemplate(elasticsearchClient, elasticsearchConverter);
20 | template.setRefreshPolicy(refreshPolicy());
21 |
22 | return template;
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/config/ElasticSearchConfig.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.config;
2 |
3 | import com.hermes.ithermes.infrastructure.elastic.JobSearchRepository;
4 | import com.hermes.ithermes.infrastructure.elastic.YoutubeAndNewsSearchRepository;
5 | import org.elasticsearch.client.RestHighLevelClient;
6 | import org.springframework.beans.factory.annotation.Value;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.data.elasticsearch.client.ClientConfiguration;
9 | import org.springframework.data.elasticsearch.client.RestClients;
10 | import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
11 |
12 | @Configuration
13 | @EnableElasticsearchRepositories(basePackageClasses = {YoutubeAndNewsSearchRepository.class, JobSearchRepository.class})
14 | public class ElasticSearchConfig extends AbstractElasticsearchConfiguration {
15 |
16 | @Value("${spring.elasticSearch.ipAddress}")
17 | private String ipAddress;
18 | @Value("${spring.elasticSearch.port}")
19 | private String port;
20 |
21 | @Override
22 | public RestHighLevelClient elasticsearchClient() {
23 | ClientConfiguration clientConfiguration = ClientConfiguration.builder()
24 | .connectedTo(ipAddress + ":" + port)
25 | .build();
26 | return RestClients.create(clientConfiguration).rest();
27 | }
28 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/controller/AlarmController.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.controller;
2 |
3 | import com.hermes.ithermes.application.AlarmService;
4 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
5 | import lombok.RequiredArgsConstructor;
6 | import org.springframework.http.ResponseEntity;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestMethod;
9 | import org.springframework.web.bind.annotation.RestController;
10 |
11 | @RestController
12 | @RequiredArgsConstructor
13 | @RequestMapping("/api/alarm")
14 | public class AlarmController {
15 |
16 | private final AlarmService alarmService;
17 |
18 | @RequestMapping(value = "/subscription",method = RequestMethod.GET)
19 | public ResponseEntity alarmSubscribeContents(){
20 | return ResponseEntity.ok(alarmService.sendSubscribeAlarm());
21 | }
22 |
23 | @RequestMapping(value = "/recommend",method = RequestMethod.GET)
24 | public ResponseEntity alarmRecommendContents(){
25 | return ResponseEntity.ok(alarmService.sendRecommendAlarm());
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/controller/ContentsController.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.controller;
2 |
3 | import com.hermes.ithermes.application.ContentsService;
4 | import com.hermes.ithermes.domain.exception.NotExistsRequestParamException;
5 | import com.hermes.ithermes.domain.util.CategoryType;
6 | import com.hermes.ithermes.domain.util.OrderType;
7 | import com.hermes.ithermes.presentation.dto.contents.CategoryCountDto;
8 | import com.hermes.ithermes.presentation.dto.contents.ContentsDtoInterface;
9 | import com.hermes.ithermes.presentation.dto.contents.SearchContentsDto;
10 | import lombok.RequiredArgsConstructor;
11 | import org.springframework.http.ResponseEntity;
12 | import org.springframework.web.bind.annotation.*;
13 |
14 | import java.util.List;
15 |
16 | @RestController
17 | @RequestMapping("/api/contents")
18 | @RequiredArgsConstructor
19 | public class ContentsController {
20 |
21 | private final ContentsService contentsService;
22 |
23 | @RequestMapping(value = "/main",method = RequestMethod.GET)
24 | public ResponseEntity> getMainContents(@RequestParam(value = "type") CategoryType type){
25 | if(!CategoryType.isContainCategoryType(type.getTitle())){
26 | throw new NotExistsRequestParamException();
27 | }
28 | return ResponseEntity.ok(contentsService.getMainContents(type));
29 | }
30 |
31 | @RequestMapping(value = "/category",method = RequestMethod.GET)
32 | public ResponseEntity> getCategoryContents(@RequestParam(value = "type") CategoryType type, @RequestParam(value = "page")int page,
33 | @RequestParam(value = "order",required = false)OrderType order){
34 | if(!CategoryType.isContainCategoryType(type.getTitle())||!OrderType.isContainOrderType(order.getName())){
35 | throw new NotExistsRequestParamException();
36 | }
37 | return ResponseEntity.ok(contentsService.getCategoryContents(type, page,order));
38 | }
39 |
40 | @RequestMapping(value = "/count",method = RequestMethod.GET)
41 | public ResponseEntity getCategoryCount(){
42 | return ResponseEntity.ok(contentsService.getCategoryCount());
43 | }
44 |
45 | @RequestMapping(value = "/search", method = RequestMethod.GET)
46 | public ResponseEntity getSearchContents(@RequestParam(value = "type")CategoryType type, @RequestParam(value = "search")String search){
47 | return ResponseEntity.ok(contentsService.getSearchContents(search,type));
48 | }
49 |
50 | @RequestMapping(value = "/deleteCache",method = RequestMethod.GET)
51 | public ResponseEntity deleteCacheContents(){
52 | contentsService.deleteContentsCache();
53 | return ResponseEntity.ok("success");
54 | }
55 |
56 | @RequestMapping(value = "/elasticsearch",method = RequestMethod.GET)
57 | public ResponseEntity updateContentsElasticSearch(){
58 | contentsService.updateElasticsearch();
59 | return ResponseEntity.ok("success");
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/controller/CrawlingContentsLastUrlController.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.controller;
2 |
3 | import com.hermes.ithermes.application.CrawlingContentsLastUrlService;
4 | import com.hermes.ithermes.presentation.dto.crawlingcontentslasttitle.CrawlingContentsLastUrlFindAllResponseDto;
5 | import lombok.RequiredArgsConstructor;
6 | import org.springframework.http.ResponseEntity;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestMethod;
9 | import org.springframework.web.bind.annotation.RestController;
10 |
11 | @RestController
12 | @RequiredArgsConstructor
13 | @RequestMapping("/api/crawling-contents-last-title")
14 | public class CrawlingContentsLastUrlController {
15 |
16 | private final CrawlingContentsLastUrlService crawlingContentsLastUrlService;
17 |
18 | @RequestMapping(value = "/",method = RequestMethod.GET)
19 | public ResponseEntity findAllCrawlingContentsLastTitle() {
20 | CrawlingContentsLastUrlFindAllResponseDto crawlingContentsLastUrlFindAllResponseDto = crawlingContentsLastUrlService.findAllCrawlingContentsLastTitle();
21 | return ResponseEntity.ok(crawlingContentsLastUrlFindAllResponseDto);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/controller/JobController.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.controller;
2 |
3 | import com.hermes.ithermes.application.JobService;
4 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
5 | import com.hermes.ithermes.presentation.dto.job.JobInsertRequestDto;
6 | import lombok.RequiredArgsConstructor;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.web.bind.annotation.RequestBody;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RequestMethod;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | import java.net.URI;
14 |
15 | @RestController
16 | @RequiredArgsConstructor
17 | @RequestMapping("/api/job")
18 | public class JobController {
19 | private final JobService jobService;
20 |
21 | @RequestMapping(value = "/",method = RequestMethod.POST)
22 | public ResponseEntity insertJob(@RequestBody JobInsertRequestDto jobInsertRequestDto){
23 | CommonResponseDto commonResponseDto = jobService.insertJob(jobInsertRequestDto);
24 | return ResponseEntity.created(URI.create("/api/job")).body(commonResponseDto);
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/controller/SubscribeController.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.controller;
2 |
3 | import com.hermes.ithermes.application.SubscribeService;
4 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
5 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeContentsDto;
6 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeFindSubscribeRequestDto;
7 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribePutSubscribeRequestDto;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.ResponseEntity;
10 | import org.springframework.web.bind.annotation.RequestBody;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.RequestMethod;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | import javax.validation.Valid;
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/api/subscribe")
20 | public class SubscribeController {
21 | private final SubscribeService subscribeService;
22 |
23 | @Autowired
24 | public SubscribeController(SubscribeService subscribeService) {
25 | this.subscribeService = subscribeService;
26 | }
27 |
28 | @RequestMapping(value = "/", method = RequestMethod.PUT)
29 | public ResponseEntity putSubscribe(@Valid @RequestBody SubscribePutSubscribeRequestDto subscribePutSubscribeRequestDto) {
30 |
31 | CommonResponseDto commonResponseDto = subscribeService.putSubscribe(subscribePutSubscribeRequestDto);
32 | return ResponseEntity.ok(commonResponseDto);
33 | }
34 |
35 | @RequestMapping(value = "/", method = RequestMethod.POST)
36 | public ResponseEntity> findSubscribe(@Valid @RequestBody SubscribeFindSubscribeRequestDto subscribeFindSubscribeRequestDto) {
37 |
38 | List subscribe = subscribeService.findSubscribe(subscribeFindSubscribeRequestDto);
39 | return ResponseEntity.ok(subscribe);
40 | }
41 |
42 | @RequestMapping(value = "/elasticsearch", method = RequestMethod.GET)
43 | public ResponseEntity updateSubscribeElasticSearch(){
44 | return ResponseEntity.ok("success");
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/controller/UrlRecordController.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.controller;
2 |
3 | import com.hermes.ithermes.application.UrlRecordService;
4 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
5 | import com.hermes.ithermes.presentation.dto.urlrecord.UrlRecordPutViewCountRequestDto;
6 | import jakarta.servlet.http.HttpServletRequest;
7 | import lombok.RequiredArgsConstructor;
8 | import org.springframework.http.ResponseEntity;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RequestMethod;
12 | import org.springframework.web.bind.annotation.RestController;
13 |
14 | import java.net.URISyntaxException;
15 |
16 | @RestController
17 | @RequiredArgsConstructor
18 | @RequestMapping("/api/url-record")
19 | public class UrlRecordController {
20 | private final UrlRecordService urlRecordService;
21 |
22 | @RequestMapping(value = "/", method = RequestMethod.POST)
23 | public ResponseEntity putViewCount(@RequestBody UrlRecordPutViewCountRequestDto urlRecordPutViewCountRequestDto, HttpServletRequest httpServletRequest) throws URISyntaxException {
24 | String ipAddress = httpServletRequest.getRemoteAddr();
25 | CommonResponseDto responseDto = urlRecordService.putViewCount(urlRecordPutViewCountRequestDto, ipAddress);
26 | return ResponseEntity.ok(responseDto);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/controller/UserController.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.controller;
2 |
3 | import com.hermes.ithermes.application.UserService;
4 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
5 | import com.hermes.ithermes.presentation.dto.user.*;
6 | import jakarta.servlet.http.HttpServletRequest;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.ResponseEntity;
9 | import org.springframework.security.core.Authentication;
10 | import org.springframework.web.bind.annotation.RequestBody;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.RequestMethod;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | import javax.validation.Valid;
16 | import java.net.URI;
17 | import java.util.List;
18 |
19 | @RestController()
20 | @RequestMapping("/api/user")
21 | public class UserController {
22 |
23 | private final UserService userService;
24 |
25 | @Autowired
26 | public UserController(UserService userService) {
27 | this.userService = userService;
28 | }
29 |
30 | @RequestMapping(value = "/join", method = RequestMethod.POST)
31 | public ResponseEntity joinUser(@Valid @RequestBody UserCreateUserRequestDto userCreateUserRequestDto) {
32 | userService.joinUser(userCreateUserRequestDto);
33 | URI uri = URI.create("/api/user/join/");
34 |
35 | return ResponseEntity.created(uri).body(userCreateUserRequestDto);
36 | }
37 |
38 | @RequestMapping(value = "/login", method = RequestMethod.POST)
39 | public ResponseEntity loginUser(@Valid @RequestBody UserLoginRequestDto userLoginRequestDto) {
40 | UserLoginResponseDto userLoginResponseDto = userService.loginUser(userLoginRequestDto);
41 | return ResponseEntity.ok().body(userLoginResponseDto);
42 | }
43 |
44 | @RequestMapping(value = "/duplicate-nickname", method = RequestMethod.POST)
45 | public ResponseEntity checkDuplicateNickname(@Valid @RequestBody UserDuplicateNicknameRequestDto userDuplicateNicknameRequestDto) {
46 | CommonResponseDto userDuplicateNicknameResponseDto = userService.checkDuplicateNickname(userDuplicateNicknameRequestDto);
47 | return ResponseEntity.ok(userDuplicateNicknameResponseDto);
48 | }
49 |
50 | @RequestMapping(value = "/duplicate-id", method = RequestMethod.POST)
51 | public ResponseEntity checkDuplicateNickname(@Valid @RequestBody UserDuplicateIdRequestDto userDuplicateIdRequestDto) {
52 | CommonResponseDto userDuplicateIdResponseDto = userService.checkDuplicateId(userDuplicateIdRequestDto);
53 | return ResponseEntity.ok(userDuplicateIdResponseDto);
54 | }
55 |
56 | @RequestMapping(value = "/nickname", method = RequestMethod.PUT)
57 | public ResponseEntity checkDuplicateNickname(@Valid @RequestBody UserUpdateNicknameRequestDto userUpdateNicknameRequestDto) {
58 | CommonResponseDto userUpdateNicknameResponseDto = userService.updateNickname(userUpdateNicknameRequestDto);
59 | return ResponseEntity.ok(userUpdateNicknameResponseDto);
60 | }
61 |
62 | @RequestMapping(value = "/user-list", method = RequestMethod.GET)
63 | public ResponseEntity> findUserList() {
64 | List userList = userService.findUserList();
65 | return ResponseEntity.ok(userList);
66 | }
67 |
68 | @RequestMapping(value = "/", method = RequestMethod.PUT)
69 | public ResponseEntity deleteUser(@Valid @RequestBody UserDeleteUserRequestDto userDeleteUserRequestDto) {
70 | CommonResponseDto commonResponseDto = userService.deleteUser(userDeleteUserRequestDto);
71 | return ResponseEntity.ok(commonResponseDto);
72 | }
73 |
74 | @RequestMapping(value = "/my-page", method = RequestMethod.POST)
75 | public ResponseEntity findMyData(@Valid @RequestBody UserFindMyDataRequestDto userFindMyDataRequestDto) {
76 | UserFindMyDataResponseDto userFindMyDataResponseDto = userService.findMyData(userFindMyDataRequestDto);
77 | return ResponseEntity.ok(userFindMyDataResponseDto);
78 | }
79 |
80 | @RequestMapping(value = "/refresh-token", method = RequestMethod.GET)
81 | public ResponseEntity checkRefreshToken(HttpServletRequest request) {
82 | String refreshToken = request.getHeader("HERMES-REFRESH-TOKEN");
83 | UserCheckRefreshTokenResponseDto userCheckRefreshTokenResponseDto = userService.checkRefreshToken(refreshToken);
84 | return ResponseEntity.ok(userCheckRefreshTokenResponseDto);
85 | }
86 |
87 | @RequestMapping(value = "/logout", method = RequestMethod.GET)
88 | public ResponseEntity logoutUser(Authentication authentication) {
89 | String loginId = authentication.getName();
90 | CommonResponseDto commonResponseDto = userService.userLogout(loginId);
91 | return ResponseEntity.ok(commonResponseDto);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/controller/YoutubeAndNewsController.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.controller;
2 |
3 | import com.hermes.ithermes.application.YoutubeAndNewsService;
4 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
5 | import com.hermes.ithermes.presentation.dto.youtubeandnews.YoutubeAndNewsInsertDto;
6 | import lombok.RequiredArgsConstructor;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.web.bind.annotation.RequestBody;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RequestMethod;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | import java.net.URI;
14 |
15 | @RestController
16 | @RequiredArgsConstructor
17 | @RequestMapping("/api/youtube-and-news")
18 | public class YoutubeAndNewsController {
19 | private final YoutubeAndNewsService youtubeAndNewsService;
20 |
21 | @RequestMapping(value = "/",method = RequestMethod.POST)
22 | public ResponseEntity parseYoutubeAndNews(@RequestBody YoutubeAndNewsInsertDto youtubeAndNewsCrawlingDtoList){
23 | CommonResponseDto commonResponseDto = youtubeAndNewsService.insertYoutubeAndNews(youtubeAndNewsCrawlingDtoList);
24 | return ResponseEntity.created(URI.create("/api/youtube-and-news")).body(commonResponseDto);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/CommonResponseDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | public class CommonResponseDto {
7 |
8 | private String message;
9 |
10 | public CommonResponseDto() {
11 | this.message = "success";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/alarm/AlarmDtoInterface.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.alarm;
2 |
3 | import com.hermes.ithermes.domain.util.ContentsProviderType;
4 |
5 | import java.time.LocalDateTime;
6 |
7 | public interface AlarmDtoInterface {
8 |
9 | String title();
10 | String description();
11 | String image();
12 | String url();
13 | LocalDateTime contentsStartAt();
14 | ContentsProviderType contentsProvider();
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/alarm/JobAlarmDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.alarm;
2 |
3 | import com.hermes.ithermes.domain.entity.Job;
4 | import com.hermes.ithermes.domain.util.ContentsProviderType;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Getter;
8 |
9 | import java.time.LocalDateTime;
10 |
11 | @Getter
12 | @Builder
13 | @AllArgsConstructor
14 | public class JobAlarmDto{
15 |
16 | private String title;
17 |
18 | private String location;
19 |
20 | private String company;
21 |
22 | private String url;
23 |
24 | private LocalDateTime contentsEndAt;
25 |
26 | private ContentsProviderType contentsProviderType;
27 |
28 | public static JobAlarmDto convertEntityToDto(Job job){
29 | return JobAlarmDto.builder()
30 | .title(job.getTitle())
31 | .location(job.getLocation())
32 | .company(job.getCompany())
33 | .url(job.getUrl())
34 | .contentsEndAt(job.getContentsEndAt())
35 | .contentsProviderType(job.getContentsProvider())
36 | .build();
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/alarm/YoutubeAndNewsAlarmDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.alarm;
2 |
3 | import com.hermes.ithermes.domain.entity.YoutubeAndNews;
4 | import com.hermes.ithermes.domain.util.ContentsProviderType;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Getter;
8 |
9 | import java.time.LocalDateTime;
10 |
11 | @Getter
12 | @AllArgsConstructor
13 | @Builder
14 | public class YoutubeAndNewsAlarmDto implements AlarmDtoInterface{
15 |
16 | private String title;
17 |
18 | private String description;
19 |
20 | private String image;
21 |
22 | private String url;
23 |
24 | private LocalDateTime contentsStartAt;
25 |
26 | private ContentsProviderType contentsProviderType;
27 |
28 | public static YoutubeAndNewsAlarmDto convertEntityToDto(YoutubeAndNews youtubeAndNews){
29 | return YoutubeAndNewsAlarmDto.builder()
30 | .title(youtubeAndNews.getTitle())
31 | .description(youtubeAndNews.getDescription())
32 | .image(youtubeAndNews.getImage())
33 | .url(youtubeAndNews.getUrl())
34 | .contentsStartAt(youtubeAndNews.getContentsStartAt())
35 | .contentsProviderType(youtubeAndNews.getContentsProvider())
36 | .build();
37 | }
38 |
39 | @Override
40 | public String title() {
41 | return title;
42 | }
43 |
44 | @Override
45 | public String description() {
46 | return description;
47 | }
48 |
49 | @Override
50 | public String image() {
51 | return image;
52 | }
53 |
54 | @Override
55 | public String url() {
56 | return url;
57 | }
58 |
59 | @Override
60 | public LocalDateTime contentsStartAt() {
61 | return contentsStartAt;
62 | }
63 |
64 | @Override
65 | public ContentsProviderType contentsProvider() {
66 | return contentsProviderType;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/contents/CategoryCountDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.contents;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Getter
8 | @AllArgsConstructor
9 | @NoArgsConstructor
10 | public class CategoryCountDto {
11 | private long youtubeCnt;
12 | private long jobCnt;
13 | private long newsCnt;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/contents/ContentsDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.contents;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
7 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
8 | import com.hermes.ithermes.domain.entity.CrawlingContents;
9 | import com.hermes.ithermes.domain.util.CategoryType;
10 | import com.hermes.ithermes.domain.util.ContentsProviderType;
11 | import lombok.AllArgsConstructor;
12 | import lombok.Builder;
13 | import lombok.Getter;
14 | import lombok.NoArgsConstructor;
15 |
16 | import java.io.Serializable;
17 | import java.time.LocalDateTime;
18 |
19 | @Getter
20 | @Builder
21 | @AllArgsConstructor
22 | @NoArgsConstructor
23 | public class ContentsDto implements ContentsDtoInterface, Serializable {
24 |
25 | public String title;
26 |
27 | public String image;
28 |
29 | public String url;
30 |
31 | public CategoryType category;
32 |
33 | public ContentsProviderType contentProvider;
34 |
35 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
36 | @JsonSerialize(using = LocalDateTimeSerializer.class)
37 | @JsonDeserialize(using = LocalDateTimeDeserializer.class)
38 | public LocalDateTime contentsDate;
39 |
40 | public String description;
41 |
42 | public Long viewCnt;
43 |
44 | public ContentsDto(CrawlingContents crawlingContents){
45 | this.title = crawlingContents.findTitle();
46 | this.image = crawlingContents.findImage();
47 | this.url = crawlingContents.findUrl();
48 | this.category = crawlingContents.findCategoryType();
49 | this.contentProvider = crawlingContents.findContentsProvider();
50 | this.contentsDate = crawlingContents.findContentsTime();
51 | this.description = crawlingContents.findDescription();
52 | this.viewCnt = crawlingContents.findViewCount();
53 | }
54 |
55 | @Override
56 | public ContentsDto convertEntityToDto(CrawlingContents crawlingContents) {
57 | return new ContentsDto(crawlingContents);
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/contents/ContentsDtoInterface.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.contents;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContents;
4 |
5 | public interface ContentsDtoInterface {
6 |
7 | ContentsDtoInterface convertEntityToDto(CrawlingContents crawlingContents);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/contents/MainPageContentsDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.contents;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
7 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
8 | import com.hermes.ithermes.domain.entity.CrawlingContents;
9 | import com.hermes.ithermes.domain.util.CategoryType;
10 | import com.hermes.ithermes.domain.util.ContentsProviderType;
11 | import lombok.AllArgsConstructor;
12 | import lombok.Builder;
13 | import lombok.Getter;
14 | import lombok.NoArgsConstructor;
15 |
16 | import java.io.Serializable;
17 | import java.time.LocalDateTime;
18 |
19 | @Getter
20 | @AllArgsConstructor
21 | @Builder
22 | @NoArgsConstructor
23 | public class MainPageContentsDto implements ContentsDtoInterface, Serializable {
24 |
25 | public String title;
26 |
27 | public String image;
28 |
29 | public String url;
30 |
31 | public CategoryType category;
32 |
33 | public ContentsProviderType contentsProviderType;
34 |
35 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
36 | @JsonSerialize(using = LocalDateTimeSerializer.class)
37 | @JsonDeserialize(using = LocalDateTimeDeserializer.class)
38 | public LocalDateTime contentsDate;
39 |
40 | public Long viewCnt;
41 |
42 | public MainPageContentsDto(CrawlingContents crawlingContents) {
43 | this.title = crawlingContents.findTitle();
44 | this.image = crawlingContents.findImage();
45 | this.url = crawlingContents.findUrl();
46 | this.category = crawlingContents.findCategoryType();
47 | this.contentsProviderType = crawlingContents.findContentsProvider();
48 | this.contentsDate = crawlingContents.findContentsTime();
49 | this.viewCnt = crawlingContents.findViewCount();
50 | }
51 |
52 | @Override
53 | public MainPageContentsDto convertEntityToDto(CrawlingContents crawlingContents) {
54 | return new MainPageContentsDto(crawlingContents);
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/contents/SearchContentsDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.contents;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | @Getter
11 | @Builder
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class SearchContentsDto {
15 |
16 | public int count;
17 |
18 | public List searchContentsList;
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/crawlingcontentslasttitle/CrawlingContentsLastUrlFindAllResponseDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.crawlingcontentslasttitle;
2 |
3 | import com.hermes.ithermes.domain.entity.CrawlingContentsLastUrl;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | @AllArgsConstructor
11 | @NoArgsConstructor
12 | @Getter
13 | public class CrawlingContentsLastUrlFindAllResponseDto {
14 | List crawlingContentsLastUrlDtoList;
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/error/EntryPointErrorResponse.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.error;
2 |
3 | import lombok.*;
4 |
5 | @Data
6 | @NoArgsConstructor
7 | @AllArgsConstructor
8 | public class EntryPointErrorResponse {
9 | private String msg;
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/error/UserErrorDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.error;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | public class UserErrorDto {
7 | private String message;
8 | private String errorData;
9 |
10 | public UserErrorDto(String message, String errorData) {
11 | this.message = message;
12 | this.errorData = errorData;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/job/JobCrawlingDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.job;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Getter
8 | @AllArgsConstructor
9 | @NoArgsConstructor
10 | public class JobCrawlingDto {
11 | private String company;
12 | private String title;
13 | private String url;
14 | private String location;
15 | private String startDate;
16 | private String endDate;
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/job/JobInsertRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.job;
2 |
3 | import com.hermes.ithermes.domain.util.ContentsProviderType;
4 | import com.hermes.ithermes.domain.util.GradeType;
5 | import com.hermes.ithermes.domain.util.JobType;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Getter;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.util.List;
11 |
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | @Getter
15 | public class JobInsertRequestDto {
16 | private ContentsProviderType contentsProvider;
17 | private GradeType grade;
18 | private JobType job;
19 | private List jobCrawlingDtoList;
20 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/subscribe/SubscribeContentsDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.subscribe;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Getter
8 | @NoArgsConstructor
9 | @AllArgsConstructor
10 | public class SubscribeContentsDto {
11 | private String contentsProvider;
12 | private String isActive;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/subscribe/SubscribeFindSubscribeRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.subscribe;
2 |
3 | import jakarta.validation.constraints.NotBlank;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 |
8 | @NoArgsConstructor
9 | @AllArgsConstructor
10 | @Getter
11 | public class SubscribeFindSubscribeRequestDto {
12 | @NotBlank(message = "아이디는 필수 입력사항 입니다.")
13 | private String id;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/subscribe/SubscribeFindSubscribeResponseDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.subscribe;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | @Getter
11 | @Builder
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class SubscribeFindSubscribeResponseDto {
15 | /** 서비스 구독 활성화 정보 */
16 | private List keywordList;
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/subscribe/SubscribePutSubscribeRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.subscribe;
2 |
3 | import jakarta.validation.constraints.NotBlank;
4 | import jakarta.validation.constraints.NotEmpty;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Getter;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.util.ArrayList;
10 |
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | @Getter
14 | public class SubscribePutSubscribeRequestDto {
15 |
16 | @NotBlank(message = "아이디는 필수 입력사항 입니다.")
17 | private String id;
18 |
19 | /**
20 | * 서비스 구독 활성화 정보, 비활성화 시, 배열에 "NON_ACTIVE" 삽입
21 | */
22 | @NotEmpty(message = "서비스정보는 필수 입력사항 입니다.")
23 | private ArrayList subscribeContentsList;
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/urlrecord/UrlRecordPutViewCountRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.urlrecord;
2 |
3 | import com.hermes.ithermes.domain.util.ContentsProviderType;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 |
8 | @AllArgsConstructor
9 | @NoArgsConstructor
10 | @Getter
11 | public class UrlRecordPutViewCountRequestDto {
12 | private String url;
13 | private ContentsProviderType contentsProviderType;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserCheckRefreshTokenResponseDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Getter;
6 |
7 | @Getter
8 | @Builder
9 | @AllArgsConstructor
10 | public class UserCheckRefreshTokenResponseDto {
11 | private String message;
12 | private String accessToken;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserCreateUserRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import com.hermes.ithermes.domain.util.JobType;
4 | import jakarta.validation.constraints.NotBlank;
5 | import jakarta.validation.constraints.NotEmpty;
6 | import jakarta.validation.constraints.Pattern;
7 | import jakarta.validation.constraints.Size;
8 | import lombok.*;
9 |
10 |
11 | @Getter
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class UserCreateUserRequestDto {
15 | @NonNull
16 | @NotBlank(message = "아이디는 필수 입력사항 입니다.")
17 | private String id;
18 | @Pattern(regexp = "(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\\W)(?=\\S+$).{8,20}",
19 | message = "비밀번호는 영문 대,소문자와 숫자, 특수기호가 적어도 1개 이상씩 포함된 8자 ~ 20자의 비밀번호여야 합니다.")
20 | private String password;
21 | @NonNull
22 | @NotBlank(message = "비밀번호 확인은 필수 입력사항 입니다.")
23 | private String passwordConfirm;
24 | @NonNull
25 | @NotBlank(message = "닉네임은 필수 입력사항 입니다.")
26 | @Size(min = 2, max = 10, message = "닉네임은 2~10자만 가능 합니다.")
27 | private String nickname;
28 | @NonNull
29 | private JobType job;
30 | @NonNull
31 | @NotBlank(message = "경력은 필수 입력사항 입니다.")
32 | private String yearOfExperience;
33 | /**
34 | * 키워드는 최대 5개, 5개 이하 일 시, 배열에 null 삽입
35 | */
36 | @NonNull
37 | @NotEmpty(message = "키워드는 필수 입력사항 입니다.")
38 | private String[] keywordList;
39 |
40 | public void encodingPassword(final String password) {
41 | this.password = password;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserDeleteUserRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.NonNull;
6 | import lombok.RequiredArgsConstructor;
7 |
8 | @RequiredArgsConstructor
9 | @NoArgsConstructor
10 | @Getter
11 | public class UserDeleteUserRequestDto {
12 | @NonNull
13 | private String id;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserDuplicateIdRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import lombok.Getter;
4 | import lombok.NonNull;
5 |
6 | @Getter
7 | public class UserDuplicateIdRequestDto {
8 | @NonNull
9 | private String id;
10 |
11 | public UserDuplicateIdRequestDto() {
12 |
13 | }
14 |
15 | public UserDuplicateIdRequestDto(@NonNull String id) {
16 | this.id = id;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserDuplicateNicknameRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import lombok.Getter;
4 | import lombok.NonNull;
5 |
6 | @Getter
7 | public class UserDuplicateNicknameRequestDto {
8 | @NonNull
9 | private String nickname;
10 |
11 | public UserDuplicateNicknameRequestDto() {
12 |
13 | }
14 |
15 | public UserDuplicateNicknameRequestDto(@NonNull String nickname) {
16 | this.nickname = nickname;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserFindMyDataRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.NonNull;
6 | import lombok.RequiredArgsConstructor;
7 |
8 | @RequiredArgsConstructor
9 | @NoArgsConstructor
10 | @Getter
11 | public class UserFindMyDataRequestDto {
12 | @NonNull
13 | private String id;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserFindMyDataResponseDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.NonNull;
6 | import lombok.RequiredArgsConstructor;
7 |
8 | @RequiredArgsConstructor
9 | @NoArgsConstructor
10 | @Getter
11 | public class UserFindMyDataResponseDto {
12 | @NonNull
13 | String id;
14 | @NonNull
15 | String nickname;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserFindUserListResponseDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeContentsDto;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Getter;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.util.List;
10 |
11 | @Builder
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | @Getter
15 | public class UserFindUserListResponseDto {
16 | String loginId;
17 | String nickname;
18 | String jobType;
19 | int yearOfExperience;
20 | List subscribeList;
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserLoginRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.NonNull;
7 |
8 | @Getter
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class UserLoginRequestDto {
12 | @NonNull
13 | private String id;
14 | @NonNull
15 | private String password;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserLoginResponseDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Getter
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class UserLoginResponseDto {
13 | private String message;
14 | private String accessToken;
15 | private String refreshToken;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/user/UserUpdateNicknameRequestDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.user;
2 |
3 | import lombok.Getter;
4 | import lombok.NonNull;
5 |
6 | @Getter
7 | public class UserUpdateNicknameRequestDto {
8 | @NonNull
9 | private String id;
10 | @NonNull
11 | private String nickname;
12 |
13 | public UserUpdateNicknameRequestDto() {
14 |
15 | }
16 |
17 | public UserUpdateNicknameRequestDto(String id, String nickname) {
18 | this.id = id;
19 | this.nickname = nickname;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/youtubeandnews/YoutubeAndNewsCrawlingDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.youtubeandnews;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Getter
8 | @AllArgsConstructor
9 | @NoArgsConstructor
10 | public class YoutubeAndNewsCrawlingDto {
11 | private String title;
12 | private String url;
13 | private String description;
14 | private String thumbnail;
15 | private String date;
16 | }
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/dto/youtubeandnews/YoutubeAndNewsInsertDto.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.dto.youtubeandnews;
2 |
3 | import com.hermes.ithermes.domain.util.CategoryType;
4 | import com.hermes.ithermes.domain.util.ContentsProviderType;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Getter;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.util.ArrayList;
10 |
11 | @Getter
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | public class YoutubeAndNewsInsertDto {
15 | private CategoryType category;
16 | private ContentsProviderType contentsProvider;
17 | ArrayList youtubeAndNewsCrawlingDtoList;
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/security/CustomAccessDeniedHandler.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.security;
2 |
3 | import com.hermes.ithermes.domain.exception.WrongIdOrPasswordException;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 | import org.springframework.security.access.AccessDeniedException;
7 | import org.springframework.security.web.access.AccessDeniedHandler;
8 | import org.springframework.stereotype.Component;
9 |
10 | @Component
11 | public class CustomAccessDeniedHandler implements AccessDeniedHandler {
12 |
13 | @Override
14 | public void handle(HttpServletRequest request, HttpServletResponse response,
15 | AccessDeniedException accessDeniedException) {
16 | throw new WrongIdOrPasswordException();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/security/CustomAuthenticationEntryPoint.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.security;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.hermes.ithermes.presentation.dto.error.EntryPointErrorResponse;
5 | import jakarta.servlet.http.HttpServletRequest;
6 | import jakarta.servlet.http.HttpServletResponse;
7 | import org.springframework.security.core.AuthenticationException;
8 | import org.springframework.security.web.AuthenticationEntryPoint;
9 |
10 | import java.io.IOException;
11 |
12 | public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
13 |
14 | @Override
15 | public void commence(HttpServletRequest request, HttpServletResponse response,
16 | AuthenticationException authException) throws IOException {
17 | String exception = request.getAttribute("exception").toString();
18 |
19 | if(exception.equals(SecurityErrorCode.WRONG_TYPE_TOKEN.getCode())) {
20 | setResponse(response, exception);
21 | return;
22 | }
23 |
24 | if(exception.equals(SecurityErrorCode.EXPIRED_TOKEN.getCode())) {
25 | setResponse(response, exception);
26 | return;
27 | }
28 |
29 | if(exception.equals(null)) {
30 | setResponse(response, "인증실패");
31 | }
32 | }
33 |
34 | private void setResponse(HttpServletResponse response, String message) throws IOException {
35 | ObjectMapper objectMapper = new ObjectMapper();
36 | EntryPointErrorResponse entryPointErrorResponse = new EntryPointErrorResponse();
37 | entryPointErrorResponse.setMsg(message);
38 | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
39 | response.setContentType("application/json;charset=UTF-8");
40 | response.setCharacterEncoding("utf-8");
41 | response.getWriter().write(objectMapper.writeValueAsString(entryPointErrorResponse));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/security/JwtFilter.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.security;
2 |
3 | import jakarta.servlet.FilterChain;
4 | import jakarta.servlet.ServletException;
5 | import jakarta.servlet.http.HttpServletRequest;
6 | import jakarta.servlet.http.HttpServletResponse;
7 | import lombok.RequiredArgsConstructor;
8 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
9 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
10 | import org.springframework.security.core.context.SecurityContextHolder;
11 | import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
12 | import org.springframework.web.filter.OncePerRequestFilter;
13 |
14 | import java.io.IOException;
15 | import java.util.List;
16 |
17 | @RequiredArgsConstructor
18 | public class JwtFilter extends OncePerRequestFilter {
19 | private final String secretKey;
20 |
21 | @Override
22 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
23 | FilterChain filterChain) throws ServletException, IOException {
24 | final String authentication = request.getHeader("HERMES-ACCESS-TOKEN");
25 |
26 | if (authentication == null || !authentication.startsWith("Bearer ")) {
27 | request.setAttribute("exception", SecurityErrorCode.WRONG_TYPE_TOKEN);
28 | filterChain.doFilter(request, response);
29 | return;
30 | }
31 |
32 | String token = authentication.split(" ")[1];
33 |
34 | if (!JwtUtil.validateToken(token, secretKey)) {
35 | logger.error("Token 만료");
36 | request.setAttribute("exception", SecurityErrorCode.EXPIRED_TOKEN);
37 | filterChain.doFilter(request, response);
38 | return;
39 | }
40 |
41 | String userName = JwtUtil.getUsername(token, secretKey);
42 |
43 | UsernamePasswordAuthenticationToken authenticationToken =
44 | new UsernamePasswordAuthenticationToken(userName, null, List.of(new SimpleGrantedAuthority("USER")));
45 |
46 | authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
47 | SecurityContextHolder.getContext().setAuthentication(authenticationToken);
48 | filterChain.doFilter(request, response);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/security/JwtUtil.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.security;
2 |
3 | import io.jsonwebtoken.Claims;
4 | import io.jsonwebtoken.Jws;
5 | import io.jsonwebtoken.Jwts;
6 | import io.jsonwebtoken.SignatureAlgorithm;
7 | import jakarta.annotation.PostConstruct;
8 | import org.springframework.beans.factory.annotation.Value;
9 | import org.springframework.stereotype.Component;
10 |
11 | import java.nio.charset.StandardCharsets;
12 | import java.util.Base64;
13 | import java.util.Date;
14 |
15 | @Component
16 | public class JwtUtil {
17 |
18 | @Value("${springboot.jwt.secret}")
19 | private String secretKey = "secretKey";
20 | private final long tokenValidMillisecond = 1000L * 60 * 60;
21 |
22 | @PostConstruct
23 | protected void init() {
24 | secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
25 | }
26 |
27 | public String createAccessToken(String userName) {
28 | Claims claims = Jwts.claims();
29 | claims.put("userName",userName);
30 | Date now = new Date();
31 |
32 | String token = Jwts.builder()
33 | .setHeaderParam("type", "jwt")
34 | .setClaims(claims)
35 | .setIssuedAt(now)
36 | .setExpiration(new Date(now.getTime() + tokenValidMillisecond))
37 | .signWith(SignatureAlgorithm.HS256, secretKey)
38 | .compact();
39 |
40 | return token;
41 | }
42 |
43 | public String createRefreshToken(String userName) {
44 | Claims claims = Jwts.claims();
45 | claims.put("userName",userName);
46 | Date now = new Date();
47 |
48 | String token = Jwts.builder()
49 | .setHeaderParam("type", "jwt")
50 | .setClaims(claims)
51 | .setIssuedAt(now)
52 | .setExpiration(new Date(now.getTime() + tokenValidMillisecond*72))
53 | .signWith(SignatureAlgorithm.HS256, secretKey)
54 | .compact();
55 |
56 | return token;
57 | }
58 |
59 | public static String getUsername(String token, String secretKey) {
60 | secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
61 | String info = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().get("userName",String.class);
62 | return info;
63 | }
64 |
65 | public static boolean validateToken(String token, String secretKey) {
66 | try {
67 | secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
68 | Jws claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
69 | return !claims.getBody().getExpiration().before(new Date());
70 | } catch (Exception e) {
71 | return false;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/security/SecurityConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.security;
2 |
3 | import com.hermes.ithermes.application.UserService;
4 | import lombok.RequiredArgsConstructor;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
12 | import org.springframework.security.config.http.SessionCreationPolicy;
13 | import org.springframework.security.web.SecurityFilterChain;
14 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
15 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
16 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
17 |
18 | @Configuration
19 | @RequiredArgsConstructor
20 | @EnableWebSecurity
21 | @EnableMethodSecurity
22 | public class SecurityConfiguration {
23 |
24 | public static final String ALLOWED_METHOD_NAMES = "GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,PATCH";
25 | private final UserService userService;
26 |
27 | @Value("${springboot.jwt.secret}")
28 | private String secretKey;
29 |
30 | @Bean
31 | public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
32 | return httpSecurity
33 | .httpBasic().disable()
34 | .csrf().disable()
35 | .cors().and()
36 | .sessionManagement()
37 | .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
38 | .and()
39 | .authorizeHttpRequests().requestMatchers("/user/login", "/user/join","/user/duplicate-id","/user/duplicate-nickname","/user/refresh-token").permitAll()
40 | .and()
41 | .authorizeHttpRequests().requestMatchers("/api/user/login", "/api/user/join","/api/user/duplicate-id","/api/user/duplicate-nickname","/api/user/refresh-token").permitAll()
42 | .and()
43 | .authorizeHttpRequests().requestMatchers("/youtube-and-news/", "/job/","/crawling-contents-last-title/","/api/alarm/recommend").permitAll()
44 | .and()
45 | .authorizeHttpRequests().requestMatchers("/api/youtube-and-news/", "/api/job/","/api/crawling-contents-last-title/","/api/alarm/subscription").permitAll()
46 | .and()
47 | .authorizeHttpRequests().requestMatchers("/contents/main","/url-record/","/contents/count").permitAll()
48 | .and()
49 | .authorizeHttpRequests().requestMatchers("/api/contents/main","/api/url-record/","/api/contents/count","/api/contents/search","/api/contents/refreshCache","/api/contents/elasticsearch").permitAll()
50 | .and()
51 | .authorizeHttpRequests().requestMatchers("/**").authenticated()
52 | .and()
53 | .exceptionHandling().accessDeniedHandler(new CustomAccessDeniedHandler())
54 | .and()
55 | .exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint())
56 | .and()
57 | .addFilterBefore(new JwtFilter(secretKey), UsernamePasswordAuthenticationFilter.class)
58 | .build();
59 | }
60 |
61 | @Bean
62 | public WebSecurityCustomizer webSecurityCustomizer(){
63 | return (web) -> web.ignoring().requestMatchers("/favicon.ico");
64 | }
65 |
66 | @Bean
67 | public WebMvcConfigurer corsConfigurer() {
68 | return new WebMvcConfigurer() {
69 | @Override
70 | public void addCorsMappings(CorsRegistry registry) {
71 | registry.addMapping("/**").allowedOrigins("http://localhost:5500");
72 | registry.addMapping("/**").allowedOrigins("http://127.0.0.1:5500");
73 | registry.addMapping("/**").allowedOrigins("http://127.0.0.1:80");
74 | registry.addMapping("/**").allowedOrigins("http://localhost:80");
75 | registry.addMapping("/**").allowedMethods(ALLOWED_METHOD_NAMES.split(","));
76 | }
77 | };
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/com/hermes/ithermes/presentation/security/SecurityErrorCode.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.security;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | public enum SecurityErrorCode {
7 | WRONG_TYPE_TOKEN("WRONG_TYPE_TOKEN"),
8 | EXPIRED_TOKEN("EXPIRED_TOKEN");
9 |
10 | private String code;
11 |
12 | SecurityErrorCode(String code) {
13 | this.code = code;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/resources/application-eun.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | datasource:
3 | driver-class-name: com.mysql.cj.jdbc.Driver
4 | url: jdbc:mysql://10.41.82.229:3306/ithermes?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true
5 | username: root
6 | password: ${PASSWORD}
7 | redis:
8 | ipAddress: 10.41.82.229
9 | elasticSearch:
10 | ipAddress: 10.41.82.229
11 | port: 9200
12 |
13 | jpa:
14 | open-in-view: true
15 | hibernate:
16 | ddl-auto: update
17 | naming:
18 | physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
19 | show-sql: true
20 | properties:
21 | hibernate.format_sql: true
22 | dialect: org.hibernate.dialect.MySQL8InnoDBDialect
23 | defer-datasource-initialization: true
24 | sql:
25 | init:
26 | mode: always
27 |
28 | springboot:
29 | jwt:
30 | secret: ${JWT_KEY}
31 |
32 | logging:
33 | level:
34 | org.hibernate.SQL: debug
35 | springframework.data.elasticsearch.client.WIRE: TRACE
36 |
37 | telegram-key: ${TELEGRAM_KEY}
--------------------------------------------------------------------------------
/src/main/resources/application-local.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | datasource:
3 | driver-class-name: com.mysql.cj.jdbc.Driver
4 | url: jdbc:mysql://localhost:3307/test_schema?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true
5 | username: ${username}
6 | password: ${password}
7 | redis:
8 | ipAddress: localhost
9 | elasticSearch:
10 | ipAddress: localhost
11 | port: 9200
12 |
13 | jpa:
14 | open-in-view: true
15 | hibernate:
16 | ddl-auto: update
17 | naming:
18 | physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
19 | show-sql: false
20 | properties:
21 | hibernate.format_sql: true
22 | dialect: org.hibernate.dialect.MySQL8InnoDBDialect
23 | defer-datasource-initialization: true
24 | sql:
25 | init:
26 | mode: always
27 |
28 | springboot:
29 | jwt:
30 | secret: ${jwt-key}
31 |
32 | logging:
33 | level:
34 | org.hibernate.SQL: debug
35 | springframework.data.elasticsearch.client.WIRE: TRACE
36 |
37 | telegram-key: ${telegram-key}
--------------------------------------------------------------------------------
/src/main/resources/application-seung.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | datasource:
3 | driver-class-name: com.mysql.cj.jdbc.Driver
4 | url: jdbc:mysql://10.41.4.73:3306/ithermes?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true
5 | username: ${DATASOURCE_USERNAME}
6 | password: ${DATASOURCE_PASSWORD}
7 | redis:
8 | ipAddress: 10.41.4.73
9 | elasticSearch:
10 | ipAddress: 10.41.4.73
11 | port: 9200
12 |
13 | jpa:
14 | open-in-view: true
15 | hibernate:
16 | ddl-auto: update
17 | naming:
18 | physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
19 | show-sql: true
20 | properties:
21 | hibernate.format_sql: true
22 | dialect: org.hibernate.dialect.MySQL8InnoDBDialect
23 | defer-datasource-initialization: true
24 | sql:
25 | init:
26 | mode: always
27 |
28 | springboot:
29 | jwt:
30 | secret: ${JWT_KEY}
31 |
32 | logging:
33 | level:
34 | org.hibernate.SQL: debug
35 | springframework.data.elasticsearch.client.WIRE: TRACE
36 |
37 | telegram-key: ${TELEGRAM_KEY}
--------------------------------------------------------------------------------
/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | datasource:
3 | driver-class-name: com.mysql.cj.jdbc.Driver
4 | url: jdbc:mysql://10.41.4.73:3306/ithermes?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true
5 | username: ithermes
6 | password: ithermes1221
7 | redis:
8 | ipAddress: localhost
9 | elasticSearch:
10 | ipAddress: localhost
11 | port: 9200
12 |
13 | jpa:
14 | open-in-view: true
15 | hibernate:
16 | ddl-auto: update
17 | naming:
18 | physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
19 | show-sql: true
20 | properties:
21 | hibernate.format_sql: true
22 | dialect: org.hibernate.dialect.MySQL8InnoDBDialect
23 | defer-datasource-initialization: true
24 | sql:
25 | init:
26 | mode: always
27 |
28 | springboot:
29 | jwt:
30 | secret: test123!@#
31 |
32 | logging:
33 | level:
34 | org.hibernate.SQL: debug
35 | springframework.data.elasticsearch.client.WIRE: TRACE
36 |
37 | telegram-key: 5810579378:AAGNSVQz1Mzn1FjMkBuL1x-5UUz9u-jXdXc
38 |
--------------------------------------------------------------------------------
/src/main/resources/ehcache.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/test/java/com/hermes/ithermes/application/ContentsServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 |
4 | import com.hermes.ithermes.domain.entity.CrawlingContents;
5 | import com.hermes.ithermes.domain.entity.YoutubeAndNews;
6 | import com.hermes.ithermes.domain.util.CategoryType;
7 | import com.hermes.ithermes.domain.util.ContentsProviderType;
8 | import com.hermes.ithermes.infrastructure.YoutubeAndNewsRepository;
9 | import com.hermes.ithermes.presentation.dto.contents.ContentsDtoInterface;
10 | import jakarta.transaction.Transactional;
11 | import org.junit.jupiter.api.Assertions;
12 | import org.junit.jupiter.api.BeforeEach;
13 | import org.junit.jupiter.api.DisplayName;
14 | import org.junit.jupiter.api.Test;
15 | import org.springframework.beans.factory.annotation.Autowired;
16 | import org.springframework.boot.test.context.SpringBootTest;
17 | import org.springframework.data.domain.PageRequest;
18 | import org.springframework.data.domain.Pageable;
19 |
20 | import java.time.LocalDateTime;
21 | import java.util.List;
22 | /*
23 | @SpringBootTest
24 | @Transactional
25 | class ContentsServiceTest {
26 |
27 | @Autowired
28 | private ContentsService contentsService;
29 |
30 | @Autowired
31 | private YoutubeAndNewsRepository youtubeAndNewsRepository;
32 |
33 | @BeforeEach
34 | void setUp() {
35 | for(int i=0; i<12; i++){
36 | YoutubeAndNews youtubeAndNews = new YoutubeAndNews((long)i,"안녕하세요","ㅎㅎㅎㅎㅎ","이미지 url","그냥 url", LocalDateTime.now(),123L,false,CategoryType.YOUTUBE, ContentsProviderType.DREAM_CODING);
37 | youtubeAndNewsRepository.save(youtubeAndNews);
38 | }
39 | }
40 |
41 | @Test
42 | @DisplayName("main contents를 11개 반환하는지 테스트")
43 | void checkMainContentsCount(){
44 | List results = contentsService.getMainContents(CategoryType.YOUTUBE);
45 | Assertions.assertEquals(11, results.size());
46 | }
47 |
48 | @Test
49 | @DisplayName("category contents 페이징 처리 테스트")
50 | void checkpaging() {
51 | Pageable pageInfo = PageRequest.of(0,2);
52 | List youtubeContents = youtubeAndNewsRepository.findYoutubeAndNewsByCategory(pageInfo, CategoryType.YOUTUBE).getContent();
53 |
54 | Assertions.assertEquals(2,youtubeContents.size());
55 | }
56 |
57 | }*/
58 |
59 |
--------------------------------------------------------------------------------
/src/test/java/com/hermes/ithermes/application/SubscribeServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.domain.entity.Subscribe;
4 | import com.hermes.ithermes.domain.entity.User;
5 | import com.hermes.ithermes.domain.exception.WrongIdOrPasswordException;
6 | import com.hermes.ithermes.domain.factory.SubscribeFactory;
7 | import com.hermes.ithermes.domain.util.ActiveType;
8 | import com.hermes.ithermes.domain.util.CategoryType;
9 | import com.hermes.ithermes.domain.util.ContentsProviderType;
10 | import com.hermes.ithermes.domain.util.JobType;
11 | import com.hermes.ithermes.infrastructure.SubscribeRepository;
12 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
13 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeContentsDto;
14 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeFindSubscribeRequestDto;
15 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribePutSubscribeRequestDto;
16 | import org.junit.jupiter.api.BeforeEach;
17 | import org.junit.jupiter.api.DisplayName;
18 | import org.junit.jupiter.api.Test;
19 | import org.junit.jupiter.api.extension.ExtendWith;
20 | import org.mockito.InjectMocks;
21 | import org.mockito.Mock;
22 | import org.mockito.junit.jupiter.MockitoExtension;
23 |
24 | import java.util.ArrayList;
25 | import java.util.List;
26 |
27 | import static org.junit.jupiter.api.Assertions.assertEquals;
28 | import static org.junit.jupiter.api.Assertions.assertThrows;
29 | import static org.mockito.ArgumentMatchers.any;
30 | import static org.mockito.Mockito.when;
31 |
32 | @ExtendWith(MockitoExtension.class)
33 | class SubscribeServiceTest {
34 | @InjectMocks
35 | private SubscribeService subscribeService;
36 | @Mock
37 | private SubscribeRepository subscribeRepository;
38 | @Mock
39 | private SubscribeFactory subscribeFactory;
40 |
41 | private Subscribe subscribe;
42 | private User user;
43 | ArrayList subscribeContentsList;
44 |
45 | @BeforeEach
46 | void setUp() {
47 | user = User.builder()
48 | .loginId("test").nickname("김승기")
49 | .password("test1234").job(JobType.BACKEND)
50 | .yearOfExperience(1)
51 | .build();
52 |
53 | subscribe = Subscribe.builder()
54 | .user(user)
55 | .category(CategoryType.JOB)
56 | .contentsProvider(ContentsProviderType.SARAMIN)
57 | .isActive(ActiveType.ACTIVE)
58 | .build();
59 |
60 | subscribeContentsList = new ArrayList<>();
61 | subscribeContentsList.add(new SubscribeContentsDto("SARAMIN","ACTIVE"));
62 | subscribeContentsList.add(new SubscribeContentsDto("WANTED","ACTIVE"));
63 | subscribeContentsList.add(new SubscribeContentsDto("CODING_WORLD","ACTIVE"));
64 | subscribeContentsList.add(new SubscribeContentsDto("NAVER","ACTIVE"));
65 | subscribeContentsList.add(new SubscribeContentsDto("YOZM","ACTIVE"));
66 | subscribeContentsList.add(new SubscribeContentsDto("NOMAD_CODERS","NON_ACTIVE"));
67 | subscribeContentsList.add(new SubscribeContentsDto("DREAM_CODING","ACTIVE"));
68 |
69 | }
70 |
71 | @Test
72 | @DisplayName("구독 데이터를 입력 시, 구독 테이블에 요청 된 정보 등록 혹은 수정 성공")
73 | void 구독_PUT_정상처리() {
74 | SubscribePutSubscribeRequestDto subscribePutSubscribeRequestDto = new SubscribePutSubscribeRequestDto("test", subscribeContentsList);
75 | assertEquals(new CommonResponseDto().getMessage(), subscribeService.putSubscribe(subscribePutSubscribeRequestDto).getMessage());
76 | }
77 |
78 | @Test
79 | @DisplayName("구독 데이터 중 로그인 아이디를 잘못 입력할 시, WrongIdOrPasswordException 던지며 구독 정보 등록 혹은 수정 실패")
80 | void 구독_PUT_실패처리() {
81 | SubscribePutSubscribeRequestDto subscribePutSubscribeRequestDto = new SubscribePutSubscribeRequestDto("test", subscribeContentsList);
82 |
83 | when(subscribeFactory.parsePutSubscribeDtoToSubscribes(any())).thenThrow(new WrongIdOrPasswordException());
84 |
85 | assertThrows(WrongIdOrPasswordException.class, () -> subscribeService.putSubscribe(subscribePutSubscribeRequestDto).getMessage());
86 | }
87 |
88 | @Test
89 | @DisplayName("유저의 아이디를 요청할 시, 유저 정보와 일치하는 구독 테이블 정보가 있다면 조회 성공")
90 | void 구독조회_존재하는_구독데이터_조회() {
91 | SubscribeFindSubscribeRequestDto subscribeFindSubscribeRequestDto = new SubscribeFindSubscribeRequestDto("test");
92 | List list = new ArrayList<>();
93 | list.add(subscribe);
94 | when(subscribeFactory.parseFindSubscribeDtoToSubscribes(any())).thenReturn(list);
95 |
96 | List responseSubscribe = subscribeService.findSubscribe(subscribeFindSubscribeRequestDto);
97 | for (int i = 0; i < responseSubscribe.size(); i++) {
98 | assertEquals(subscribeContentsList.get(i).getIsActive(), responseSubscribe.get(i).getIsActive());
99 | }
100 | }
101 |
102 | @Test
103 | @DisplayName("유저의 아이디를 요청할 시, 유저 정보와 일치하는 구독 테이블 정보가 있다면 비활성화 데이터를 보내며 조회 성공")
104 | void 구독조회_존재하지않는_구독데이터_조회() {
105 | SubscribeFindSubscribeRequestDto subscribeFindSubscribeRequestDto = new SubscribeFindSubscribeRequestDto("test");
106 | List list = new ArrayList<>();
107 | when(subscribeFactory.parseFindSubscribeDtoToSubscribes(any())).thenReturn(list);
108 |
109 | List responseSubscribe = subscribeService.findSubscribe(subscribeFindSubscribeRequestDto);
110 | assertEquals(list.size(), responseSubscribe.size());
111 | }
112 |
113 | @Test
114 | @DisplayName("유저의 아이디를 요청할 시, 유저의 아이디 정보가 테이블에 없다면 WrongIdOrPasswordException 던지며 구독 정보 등록 혹은 수정 실패")
115 | void 구독조회_로그인_실패처리() {
116 | SubscribeFindSubscribeRequestDto subscribeFindSubscribeRequestDto = new SubscribeFindSubscribeRequestDto("aaaa");
117 | when(subscribeFactory.parseFindSubscribeDtoToSubscribes(any())).thenThrow(new WrongIdOrPasswordException());
118 | assertThrows(WrongIdOrPasswordException.class, () -> subscribeService.findSubscribe(subscribeFindSubscribeRequestDto));
119 | }
120 | }
--------------------------------------------------------------------------------
/src/test/java/com/hermes/ithermes/application/UserServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.application;
2 |
3 | import com.hermes.ithermes.domain.entity.Keyword;
4 | import com.hermes.ithermes.domain.entity.User;
5 | import com.hermes.ithermes.domain.entity.UserKeywordRegistry;
6 | import com.hermes.ithermes.domain.exception.SameIdException;
7 | import com.hermes.ithermes.domain.exception.SameNicknameException;
8 | import com.hermes.ithermes.domain.exception.UnMatchedPasswordException;
9 | import com.hermes.ithermes.domain.exception.WrongIdOrPasswordException;
10 | import com.hermes.ithermes.domain.factory.KeywordFactory;
11 | import com.hermes.ithermes.domain.factory.RedisFactory;
12 | import com.hermes.ithermes.domain.factory.UserFactory;
13 | import com.hermes.ithermes.domain.factory.UserKeywordRegistryFactory;
14 | import com.hermes.ithermes.domain.util.JobType;
15 | import com.hermes.ithermes.infrastructure.UserKeywordRegistryRepository;
16 | import com.hermes.ithermes.presentation.dto.CommonResponseDto;
17 | import com.hermes.ithermes.presentation.dto.user.UserCreateUserRequestDto;
18 | import com.hermes.ithermes.presentation.dto.user.UserFindMyDataRequestDto;
19 | import com.hermes.ithermes.presentation.dto.user.UserLoginRequestDto;
20 | import com.hermes.ithermes.presentation.dto.user.UserUpdateNicknameRequestDto;
21 | import com.hermes.ithermes.presentation.security.JwtUtil;
22 | import org.junit.jupiter.api.BeforeEach;
23 | import org.junit.jupiter.api.DisplayName;
24 | import org.junit.jupiter.api.Test;
25 | import org.junit.jupiter.api.extension.ExtendWith;
26 | import org.mockito.InjectMocks;
27 | import org.mockito.Mock;
28 | import org.mockito.junit.jupiter.MockitoExtension;
29 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
30 |
31 | import java.util.Optional;
32 |
33 | import static org.junit.jupiter.api.Assertions.assertEquals;
34 | import static org.junit.jupiter.api.Assertions.assertThrows;
35 | import static org.mockito.ArgumentMatchers.any;
36 | import static org.mockito.Mockito.when;
37 |
38 | @ExtendWith(MockitoExtension.class)
39 | class UserServiceTest {
40 |
41 | @InjectMocks
42 | private UserService userService;
43 | @Mock
44 | private UserKeywordRegistryRepository userKeywordRegistryRepository;
45 | @Mock
46 | private UserKeywordRegistryFactory userKeywordRegistryFactory;
47 | @Mock
48 | private UserFactory userFactory;
49 | @Mock
50 | private KeywordFactory keywordFactory;
51 | @Mock
52 | private BCryptPasswordEncoder encoder;
53 | @Mock
54 | private JwtUtil jwtUtil;
55 | @Mock
56 | private RedisFactory redisFactory;
57 |
58 |
59 | private UserCreateUserRequestDto userCreateUserRequestDto;
60 | private User user;
61 | private UserKeywordRegistry userKeywordRegistry;
62 | private Keyword keyword;
63 |
64 | @BeforeEach
65 | void setUp() {
66 | user = User.builder()
67 | .loginId("test").nickname("김승기")
68 | .password("test1234!").job(JobType.BACKEND)
69 | .yearOfExperience(1)
70 | .build();
71 |
72 | keyword = Keyword.builder().name("머신러닝").build();
73 |
74 | userKeywordRegistry = UserKeywordRegistry.builder()
75 | .user(user)
76 | .keyword(keyword)
77 | .build();
78 | }
79 |
80 | @Test
81 | @DisplayName("회원가입 시 회원정보, 키워드가 테이블에 저장되어 회원가입 성공")
82 | void 회원가입_정상처리() {
83 | userCreateUserRequestDto = new UserCreateUserRequestDto("test", "test1234!",
84 | "test1234!", "김승기", JobType.BACKEND, "1", new String[]{"프론트", "백엔드", "인공지능", null, null});
85 |
86 | when(userFactory.existsByLoginId(any())).thenReturn(false);
87 | when(userFactory.parseLoginRequestDtoToUser(any())).thenReturn(user);
88 | when(userKeywordRegistryFactory.parseUserAndKeyword(any(), any())).thenReturn(userKeywordRegistry);
89 |
90 | assertEquals(new CommonResponseDto().getMessage(), userService.joinUser(userCreateUserRequestDto).getMessage());
91 | }
92 |
93 | @Test
94 | @DisplayName("회원가입 시 아이디가 유저테이블에 저장 된 데이터와 일치 할 시 SameIdException 던지며 회원가입 실패")
95 | void 회원가입_이미존재하는회원() {
96 | UserCreateUserRequestDto userCreateUserRequestDtoTest = new UserCreateUserRequestDto("test", "1q2w3e4r",
97 | "1q2w3e4r", "김승기", JobType.BACKEND, "1"
98 | , new String[]{"프론트", "백엔드", "인공지능", "빅데이터", "머신러닝"});
99 |
100 | when(userFactory.existsByLoginId(any())).thenReturn(true);
101 |
102 | assertThrows(SameIdException.class, () -> userService.joinUser(userCreateUserRequestDtoTest));
103 |
104 | }
105 |
106 | @Test
107 | @DisplayName("회원가입 시 입력한 비밀번호와 비밀번호확인 데이터가 다를 경우 UnMatchedPasswordException 던지며 회원가입 실패")
108 | void 회원가입_비밀번호불일치() {
109 | UserCreateUserRequestDto userCreateUserRequestDtoTest = new UserCreateUserRequestDto("test", "1q2w3e4r",
110 | "1q2w3e4r!!", "김승기", JobType.BACKEND, "1"
111 | , new String[]{"프론트", "백엔드", "인공지능", "빅데이터", "머신러닝"});
112 |
113 | assertThrows(UnMatchedPasswordException.class, () -> userService.joinUser(userCreateUserRequestDtoTest));
114 | }
115 |
116 | @Test
117 | @DisplayName("유저 테이블에 존재하지 하는 아이디 패스워드를 입력하는 경우 로그인 성공")
118 | void 로그인_정상처리() {
119 | //Given
120 | String id = "kimsk";
121 | String password = "kimsk1234";
122 | UserLoginRequestDto userLoginRequestDto = new UserLoginRequestDto(id, password);
123 |
124 | //When
125 | when(userFactory.findLoginId(any())).thenReturn(Optional.ofNullable(user));
126 | when(jwtUtil.createAccessToken(any())).thenReturn("1q2w3e4r!");
127 | when(jwtUtil.createRefreshToken(any())).thenReturn("1q2w3e4r!");
128 | when(encoder.matches(any(), any())).thenReturn(true);
129 | when(redisFactory.setRedisRefreshToken(any(),any())).thenReturn("1q2w3e4r!");
130 | //Then
131 | assertEquals("success", userService.loginUser(userLoginRequestDto).getMessage());
132 | }
133 |
134 | @Test
135 | @DisplayName("유저 테이블에 존재하지 않은 아이디 패스워드를 입력하는 경우 WrongIdOrPasswordException 던지며 로그인 실패")
136 | void 로그인_회원정보불일치() {
137 | //Given
138 | String id = "kimsk";
139 | String password = "kimsk1234";
140 | UserLoginRequestDto userLoginRequestDto = new UserLoginRequestDto(id, password);
141 |
142 | //When
143 | when(userFactory.findLoginId(any())).thenThrow(new WrongIdOrPasswordException());
144 |
145 | //Then
146 | assertThrows(WrongIdOrPasswordException.class, () -> userService.loginUser(userLoginRequestDto));
147 | }
148 |
149 | @Test
150 | @DisplayName("유저테이블에 입력한 닉네임이 존재하지 않을 경우 닉네임 수정 성공")
151 | void 닉네임수정_정상처리() {
152 | //Given
153 | String loginId = "kimsk";
154 | String nickname = "kimsk123";
155 |
156 | UserUpdateNicknameRequestDto userUpdateNicknameRequestDto = new UserUpdateNicknameRequestDto(loginId, nickname);
157 |
158 | when(userFactory.existsByNickname(any())).thenReturn(false);
159 | when(userFactory.findLoginId(any())).thenReturn(Optional.of(user));
160 | //Then
161 | assertEquals(new CommonResponseDto().getMessage(), userService.updateNickname(userUpdateNicknameRequestDto).getMessage());
162 | }
163 |
164 | @Test
165 | @DisplayName("유저테이블에 입력한 닉네임이 존재할 경우 SameNicknameException 던지며 닉네임 수정 실패")
166 | void 닉네임수정_닉네임중복() {
167 | //Given
168 | String loginId = "test";
169 | String nickname = "김승기";
170 |
171 | //When
172 | UserUpdateNicknameRequestDto userUpdateNicknameRequestDto = new UserUpdateNicknameRequestDto(loginId, nickname);
173 | when(userFactory.existsByNickname(nickname)).thenReturn(true);
174 |
175 | //Then
176 | assertThrows(SameNicknameException.class, () -> userService.updateNickname(userUpdateNicknameRequestDto));
177 | }
178 |
179 | @Test
180 | @DisplayName("유저 테이블에 존재하는 아이디를 입력했을 경우 유저 데이터 조회 성공")
181 | void 마이페이지_정상처리() {
182 | //Given
183 | String loginId = "test";
184 | UserFindMyDataRequestDto userFindMyDataRequestDto = new UserFindMyDataRequestDto(loginId);
185 |
186 | //When
187 | when(userFactory.findLoginId(any())).thenReturn(Optional.of(user));
188 |
189 | //Then
190 | assertEquals(loginId, userService.findMyData(userFindMyDataRequestDto).getId());
191 | assertEquals("김승기", userService.findMyData(userFindMyDataRequestDto).getNickname());
192 |
193 | }
194 |
195 | @Test
196 | @DisplayName("유저 테이블에 존재하지 않는 아이디를 입력했을 경우 WrongIdOrPasswordException 던지며 유저 데이터 조회 실패")
197 | void 마이페이지_존재하지않는회원() {
198 | //Given
199 | String loginId = "dfjerioghjeruiojgheruih";
200 | UserFindMyDataRequestDto userFindMyDataRequestDto = new UserFindMyDataRequestDto(loginId);
201 |
202 | //When
203 | when(userFactory.findLoginId(any())).thenReturn(Optional.ofNullable(null));
204 |
205 | //Then
206 | assertThrows(WrongIdOrPasswordException.class, () -> userService.findMyData(userFindMyDataRequestDto));
207 | }
208 | }
--------------------------------------------------------------------------------
/src/test/java/com/hermes/ithermes/presentation/controller/SubscribeControllerTest.java:
--------------------------------------------------------------------------------
1 | package com.hermes.ithermes.presentation.controller;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.hermes.ithermes.application.SubscribeService;
5 | import com.hermes.ithermes.domain.exception.WrongIdOrPasswordException;
6 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeContentsDto;
7 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribeFindSubscribeRequestDto;
8 | import com.hermes.ithermes.presentation.dto.subscribe.SubscribePutSubscribeRequestDto;
9 | import org.junit.jupiter.api.DisplayName;
10 | import org.junit.jupiter.api.Test;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa;
13 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
14 | import org.springframework.boot.test.mock.mockito.MockBean;
15 | import org.springframework.http.MediaType;
16 | import org.springframework.security.test.context.support.WithMockUser;
17 | import org.springframework.test.web.servlet.MockMvc;
18 |
19 | import java.util.ArrayList;
20 |
21 | import static org.mockito.ArgumentMatchers.any;
22 | import static org.mockito.Mockito.when;
23 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
24 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
25 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
26 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
27 |
28 | @WebMvcTest(controllers = SubscribeController.class)
29 | @AutoConfigureDataJpa
30 | class SubscribeControllerTest {
31 |
32 | @MockBean
33 | private SubscribeService subscribeService;
34 |
35 | @Autowired
36 | private MockMvc mockMvc;
37 |
38 | @Autowired
39 | ObjectMapper objectMapper;
40 |
41 | @Test
42 | @DisplayName("구독_PUT_정상처리")
43 | @WithMockUser
44 | void 구독_PUT_정상처리() throws Exception {
45 | ArrayList subscribeContentsList = new ArrayList<>();
46 | subscribeContentsList.add(new SubscribeContentsDto("SARAMIN","ACTIVE"));
47 | subscribeContentsList.add(new SubscribeContentsDto("WANTED","ACTIVE"));
48 | subscribeContentsList.add(new SubscribeContentsDto("CODING_WORLD","ACTIVE"));
49 | subscribeContentsList.add(new SubscribeContentsDto("NAVER","ACTIVE"));
50 | subscribeContentsList.add(new SubscribeContentsDto("YOZM","ACTIVE"));
51 | subscribeContentsList.add(new SubscribeContentsDto("NOMAD_CODERS","NON_ACTIVE"));
52 | subscribeContentsList.add(new SubscribeContentsDto("DREAM_CODING","ACTIVE"));
53 |
54 | SubscribePutSubscribeRequestDto subscribePutSubscribeRequestDto = new SubscribePutSubscribeRequestDto("test",subscribeContentsList);
55 |
56 | mockMvc.perform(put("/api/subscribe/")
57 | .with(csrf())
58 | .contentType(MediaType.APPLICATION_JSON)
59 | .content(objectMapper.writeValueAsString(subscribePutSubscribeRequestDto)))
60 | .andExpect(status().isOk()); // 추후 201로 수정필요!
61 | }
62 |
63 | @Test
64 | @DisplayName("구독_PUT_실패처리")
65 | @WithMockUser
66 | void 구독_PUT_실패처리() throws Exception {
67 | ArrayList subscribeContentsList = new ArrayList<>();
68 | subscribeContentsList.add(new SubscribeContentsDto("SARAMIN","ACTIVE"));
69 | subscribeContentsList.add(new SubscribeContentsDto("WANTED","ACTIVE"));
70 | subscribeContentsList.add(new SubscribeContentsDto("CODING_WORLD","ACTIVE"));
71 | subscribeContentsList.add(new SubscribeContentsDto("NAVER","ACTIVE"));
72 | subscribeContentsList.add(new SubscribeContentsDto("YOZM","ACTIVE"));
73 | subscribeContentsList.add(new SubscribeContentsDto("NOMAD_CODERS","NON_ACTIVE"));
74 | subscribeContentsList.add(new SubscribeContentsDto("DREAM_CODING","ACTIVE"));
75 |
76 | SubscribePutSubscribeRequestDto subscribePutSubscribeRequestDto = new SubscribePutSubscribeRequestDto("test",subscribeContentsList);
77 |
78 | when(subscribeService.putSubscribe(any())).thenThrow(new WrongIdOrPasswordException());
79 |
80 | mockMvc.perform(put("/api/subscribe/")
81 | .with(csrf())
82 | .contentType(MediaType.APPLICATION_JSON)
83 | .content(objectMapper.writeValueAsString(subscribePutSubscribeRequestDto)))
84 | .andExpect(status().isBadRequest());
85 | }
86 |
87 | @Test
88 | @DisplayName("구독조회_성공처리")
89 | @WithMockUser
90 | void 구독조회_성공처리() throws Exception {
91 | SubscribeFindSubscribeRequestDto subscribeFindSubscribeRequestDto = new SubscribeFindSubscribeRequestDto("test");
92 |
93 | mockMvc.perform(post("/api/subscribe/")
94 | .with(csrf())
95 | .contentType(MediaType.APPLICATION_JSON)
96 | .content(objectMapper.writeValueAsString(subscribeFindSubscribeRequestDto)))
97 | .andExpect(status().isOk());
98 | }
99 |
100 | @Test
101 | @DisplayName("구독조회_실패처리")
102 | @WithMockUser
103 | void 구독조회_실패처리() throws Exception {
104 | SubscribeFindSubscribeRequestDto subscribeFindSubscribeRequestDto = new SubscribeFindSubscribeRequestDto("test");
105 |
106 | when(subscribeService.findSubscribe(any())).thenThrow(new WrongIdOrPasswordException());
107 |
108 | mockMvc.perform(post("/api/subscribe/")
109 | .with(csrf())
110 | .contentType(MediaType.APPLICATION_JSON)
111 | .content(objectMapper.writeValueAsString(subscribeFindSubscribeRequestDto)))
112 | .andExpect(status().isBadRequest());
113 | }
114 | }
--------------------------------------------------------------------------------
/src/test/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | datasource:
3 | driver-class-name: org.h2.Driver
4 | url: jdbc:h2:mem:hermes;MODE=MYSQL
5 | username: sa
6 | password:
7 | redis:
8 | ipAddress: localhost
9 | h2:
10 | console:
11 | enabled: true
12 |
13 | jpa:
14 | hibernate:
15 | ddl-auto: create
16 | properties:
17 | hibernate:
18 | show_sql: true
19 | format_sql: true
20 | jdbc:
21 | time_zone: Asia/Seoul
22 | defer-datasource-initialization: true
23 |
24 | springboot:
25 | jwt:
26 | secret: test123!@#
27 |
28 | logging:
29 | level:
30 | org.hibernate.SQL: debug
31 |
32 | telegram-key: "5810579378:AAGNSVQz1Mzn1FjMkBuL1x-5UUz9u-jXdXc"
--------------------------------------------------------------------------------