Skip to content

Commit

Permalink
Merge pull request #57 from TeamDMU/develop
Browse files Browse the repository at this point in the history
[Release] version 1.2.0
  • Loading branch information
GiJungPark authored Nov 10, 2024
2 parents b3e0fe6 + 178229e commit 3f83e28
Show file tree
Hide file tree
Showing 177 changed files with 8,374 additions and 84 deletions.
84 changes: 84 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: CI Auto Test

on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up JDK
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'

- name: Create MySQL resources directory
run: |
mkdir -p ./dmforu-infrastructure/storage/mysql/src/main/resources
- name: make mysql.yml
run: |
touch ./mysql.yml
echo "${{ secrets.MYSQL }}" | base64 --decode > ./mysql.yml
working-directory: ./dmforu-infrastructure/storage/mysql/src/main/resources

- name: Create MongoDB resources directory
run: |
mkdir -p ./dmforu-infrastructure/storage/mongo/src/main/resources
- name: make mongo.yml
run: |
touch ./mongo.yml
echo "${{ secrets.MONGO }}" | base64 --decode > ./mongo.yml
working-directory: ./dmforu-infrastructure/storage/mongo/src/main/resources

- name: Create SQS resources directory
run: |
mkdir -p ./dmforu-infrastructure/sqs/src/main/resources
- name: make sqs.yml
run: |
touch ./sqs.yml
echo "${{ secrets.SQS }}" | base64 --decode > ./sqs.yml
working-directory: ./dmforu-infrastructure/sqs/src/main/resources

- name: Create Firebase key resources directory
run: |
mkdir -p ./dmforu-infrastructure/fcm/src/main/resources/key
- name: create JSON file
run: |
echo '{
"type": "${{ secrets.FCM_TYPE }}",
"project_id": "${{ secrets.FCM_PROJECT_ID }}",
"private_key_id": "${{ secrets.FCM_PRIVATE_KEY_ID }}",
"private_key": "${{ secrets.FCM_PRIVATE_KEY }}",
"client_email": "${{ secrets.FCM_CLIENT_EMAIL }}",
"client_id": "${{ secrets.FCM_CLIENT_ID }}",
"auth_uri": "${{ secrets.FCM_AUTH_URI }}",
"token_uri": "${{ secrets.FCM_TOKEN_URI }}",
"auth_provider_x509_cert_url": "${{ secrets.FCM_AUTH_PROVIDER_X509_CERT_URL }}",
"client_x509_cert_url": "${{ secrets.FCM_CLIENT_X509_CERT_URL }}",
"universe_domain": "${{ secrets.FCM_UNIVERSE_DOMAIN }}"
}' > ./fire-base-key.json
working-directory: ./dmforu-infrastructure/fcm/src/main/resources/key

- name: Test
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
arguments: testCodeCoverageReport

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: '**/jacoco/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml'
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@ out/
.kotlin

### Configuration Settings ###
**/application.yml
**/mongo.yml
**/mysql.yml
**/sqs.yml
**/fire-base-key.json
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# DMU-BackEnd
동양미래대학교 홈페이지의 정보들을 활용하여 더 나은 편리성을 제공하기 위해 만들어진 API 서버입니다. <br>


## 아키텍처
### Infrastructure
<img width="1000" alt="DMforU 아키텍처" src="https://github.com/user-attachments/assets/c0534dff-f7e7-4df4-a2a6-6bb9d69f5d7b">

### API Project
<img width="700" alt="DMforU 아키텍처" src="https://github.com/user-attachments/assets/96102a3a-18e2-4667-ab6b-fc93df4e7831">

### Admin Project
<img width="700" alt="DMforU 아키텍처" src="https://github.com/user-attachments/assets/49ee1154-2af5-49f9-b64f-4a9918edce9b">

46 changes: 37 additions & 9 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
kotlin("plugin.spring") apply false
id("org.springframework.boot") apply false
id("io.spring.dependency-management")
id("jacoco")
}

java {
Expand All @@ -28,18 +29,14 @@ subprojects {
apply(plugin = "org.jetbrains.kotlin.plugin.spring")
apply(plugin = "org.springframework.boot")
apply(plugin = "io.spring.dependency-management")

dependencyManagement {
val springCloudDependenciesVersion: String by project
imports{
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${springCloudDependenciesVersion}")
}
}
apply(plugin = "jacoco")

dependencies {
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.jetbrains.kotlin:kotlin-reflect")
testImplementation("org.springframework.boot:spring-boot-starter-test")
if (project.name != "dmforu-domain" && project.name != "dmforu-crawling") {
implementation("org.springframework.boot:spring-boot-starter")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
Expand All @@ -60,5 +57,36 @@ subprojects {

tasks.withType<Test> {
useJUnitPlatform()
finalizedBy(tasks.jacocoTestReport)
}

tasks.jacocoTestReport {
dependsOn(tasks.test)
reports {
html.required.set(true)
xml.required.set(true)
}
classDirectories.setFrom(
files(
classDirectories.files.map {
fileTree(it) {
exclude(
"**/*Application*",
"**/*Config*",
"**/*Dto*",
"**/*Error*",
"**/request/**",
"**/response/**",
"**/*Request*",
"**/*Response*",
"**/*Interceptor*",
"**/*Exception*",
"**/*TestSupport*"
)
}
}
)
)
}

}
10 changes: 10 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
codecov:
require_ci_to_pass: yes

comment:
layout: "reach,diff,flags,files,footer"
behavior: default
require_changes: false
branches:
- develop
- main
21 changes: 21 additions & 0 deletions dmforu-admin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
tasks.getByName("bootJar") {
enabled = true
}

tasks.getByName("jar") {
enabled = false
}

dependencies {
implementation(project(":dmforu-domain"))
implementation(project(":dmforu-crawling"))
implementation(project(":dmforu-support:monitoring"))

implementation("org.springframework.boot:spring-boot-starter-web")

runtimeOnly(project(":dmforu-infrastructure:sqs"))
runtimeOnly(project(":dmforu-infrastructure:storage:mysql"))
runtimeOnly(project(":dmforu-infrastructure:storage:mongo"))

testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0")
}
23 changes: 23 additions & 0 deletions dmforu-admin/src/main/kotlin/com/dmforu/admin/AdminApplication.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.dmforu.admin

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.scheduling.annotation.EnableScheduling
import java.util.*

@SpringBootApplication(
scanBasePackages = [
"com.dmforu.admin",
"com.dmforu.sqs",
"com.dmforu.storage.db.mongo",
"com.dmforu.storage.db.mysql"
]
)
@EnableScheduling
class AdminApplication

fun main(args: Array<String>) {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"))
SpringApplicationBuilder(AdminApplication::class.java)
.run(*args)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.dmforu.admin.config

import com.dmforu.crawling.loader.JsoupHtmlLoader
import com.dmforu.crawling.parser.DepartmentNoticeParser
import com.dmforu.crawling.parser.DietParser
import com.dmforu.crawling.parser.ScheduleParser
import com.dmforu.crawling.parser.UniversityNoticeParser
import com.dmforu.domain.diet.DietRepository
import com.dmforu.domain.diet.DietWriter
import com.dmforu.domain.notice.NoticeReader
import com.dmforu.domain.notice.NoticeRepository
import com.dmforu.domain.notice.NoticeWriter
import com.dmforu.domain.schedule.ScheduleRepository
import com.dmforu.domain.schedule.ScheduleWriter
import com.dmforu.domain.subscribe.*
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Scope

@Configuration
class ApplicationConfig {

@Bean
fun subscribeReader(subscribeRepository: SubscribeRepository): SubscribeReader {
return SubscribeReader(subscribeRepository = subscribeRepository)
}

@Bean
fun noticeReader(noticeRepository: NoticeRepository): NoticeReader {
return NoticeReader(noticeRepository = noticeRepository)
}

@Bean
fun noticeWriter(noticeRepository: NoticeRepository): NoticeWriter {
return NoticeWriter(noticeRepository = noticeRepository)
}

@Bean
fun scheduleWriter(scheduleRepository: ScheduleRepository): ScheduleWriter {
return ScheduleWriter(scheduleRepository = scheduleRepository)
}

@Bean
fun dietWriter(dietRepository: DietRepository): DietWriter {
return DietWriter(dietRepository = dietRepository)
}

@Scope("prototype")
@Bean
fun departmentNoticeParser(): DepartmentNoticeParser {
return DepartmentNoticeParser(htmlLoader = JsoupHtmlLoader())
}

@Scope("prototype")
@Bean
fun universityNoticeParser(): UniversityNoticeParser {
return UniversityNoticeParser(htmlLoader = JsoupHtmlLoader())
}

@Bean
fun dietParser(): DietParser {
return DietParser(htmlLoader = JsoupHtmlLoader())
}

@Bean
fun scheduleParser(): ScheduleParser {
return ScheduleParser(htmlLoader = JsoupHtmlLoader())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.dmforu.admin.message

import com.dmforu.domain.message.Keywords
import org.springframework.stereotype.Component

@Component
class KeywordFilter {

fun extractKeywordFrom(title: String): String? {
val whiteSpaceRemovedTitle = title.replace(" ", "")

Keywords.entries.forEach {
if (whiteSpaceRemovedTitle.contains(it.korean)) {
return it.korean
}
}

if (whiteSpaceRemovedTitle.contains("중간고사")) {
return "시험"
}

if (whiteSpaceRemovedTitle.contains("기말고사")) {
return "시험"
}

return null
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.dmforu.admin.message

import com.dmforu.domain.message.MessageSender
import com.dmforu.domain.message.NoticeMessage
import com.dmforu.domain.notice.Notice
import com.dmforu.domain.subscribe.SubscribeReader
import org.springframework.stereotype.Service

@Service
class MessageService(
private val subscribeReader: SubscribeReader,
private val keywordFilter: KeywordFilter,
private val messageSender: MessageSender,
) {

fun sendNoticeMessage(notice: Notice) {
if (notice.isUniversityNotice()) {
sendUniversityNoticeMessage(notice)

return
}

sendDepartmentNoticeMessage(notice)
}

private fun sendUniversityNoticeMessage(notice: Notice) {
val keyword = keywordFilter.extractKeywordFrom(notice.title) ?: return

val tokens = subscribeReader.getTokensBySubscribedToKeyword(keyword = keyword)

if (tokens.isEmpty()) {
return
}

val message = NoticeMessage.createUniversityNoticeMessage(notice = notice, keyword = keyword)

messageSender.sendNoticeMessage(message = message, tokens = tokens)
}

private fun sendDepartmentNoticeMessage(notice: Notice) {
val tokens = subscribeReader.getTokensBySubscribedToDepartment(department = notice.type)

if (tokens.isEmpty()) {
return
}

val message = NoticeMessage.createDepartmentNoticeMessage(notice = notice)

messageSender.sendNoticeMessage(message = message, tokens = tokens)
}


}
Loading

0 comments on commit 3f83e28

Please sign in to comment.