Skip to content

Commit

Permalink
feat: #39 학급 open api batch로 가져오기
Browse files Browse the repository at this point in the history
  • Loading branch information
sominyun committed May 6, 2024
1 parent 108f1aa commit de909a3
Show file tree
Hide file tree
Showing 17 changed files with 198 additions and 191 deletions.
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ dependencies {
runtimeOnly("com.mysql:mysql-connector-j")

// mongodb
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
// implementation("org.springframework.boot:spring-boot-starter-data-mongodb")

// security
implementation("org.springframework.boot:spring-boot-starter-security")
Expand Down Expand Up @@ -85,6 +85,7 @@ dependencies {

// webclient
implementation("org.springframework.boot:spring-boot-starter-webflux")

//JSON
implementation("org.json:json:20231013")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.asap.asapbackend.batch.classroom

import com.asap.asapbackend.domain.classroom.domain.model.Classroom
import com.asap.asapbackend.domain.school.domain.model.School

interface ClassroomInfoProvider {
fun retrieveClassroomInfo(batchSize: Int, startIndex: Int): ClassroomDataContainer

data class ClassroomDataContainer(
val classroomInfo: List<ClassroomInfo>,
val hasNext: Boolean
)

data class ClassroomInfo(
val school: School,
val grade: Int,
val classNumber: String
) {
fun toClassroom(): Classroom {
return Classroom(
school = school,
grade = grade,
className = classNumber
)
}
}
}

fun List<ClassroomInfoProvider.ClassroomInfo>.toClassrooms(): List<Classroom> {
return this.map { it.toClassroom() }
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
package com.asap.asapbackend.batch.classroom

import com.asap.asapbackend.domain.classroom.domain.service.ClassroomAppender
import com.asap.asapbackend.global.util.TransactionUtils
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.stereotype.Component

@RestController
@Component
class ClassroomScheduler(
private val classroomService: ClassroomService
private val classroomInfoProvider: ClassroomInfoProvider,
private val classroomAppender: ClassroomAppender
) {
@Scheduled(cron = "0 0 4 1 3 ?") // 매년 3월 1일 04:00:00에 실행
@GetMapping("/addClassroom")
fun addClassroom(){
classroomService.addClassroom()
fun addClassroom() {
val batchSize = 100
var startIndex = 1
do {
val classroomDataContainer = classroomInfoProvider.retrieveClassroomInfo(batchSize, startIndex)

startIndex += batchSize

TransactionUtils.writable {
classroomAppender.addClassroom(classroomDataContainer.classroomInfo.toClassrooms())
}
} while (classroomDataContainer.hasNext)
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.asap.asapbackend.batch.school

import com.asap.asapbackend.client.openapi.school.dto.SchoolInfo
import com.asap.asapbackend.domain.school.domain.model.School

interface SchoolInfoProvider {
Expand All @@ -16,8 +15,8 @@ interface SchoolInfoProvider {
val eduOfficeCode: String, //ATPT_OFCDC_SC_CODE
val schoolCode: String, //SD_SCHUL_CODE
val school: String, //SCHUL_NM
val address:String //ORG_RDNMA
){
val address: String //ORG_RDNMA
) {
fun toSchool(): School {
return School(
eduOfficeCode = eduOfficeCode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,18 @@ package com.asap.asapbackend.batch.school

import com.asap.asapbackend.domain.school.domain.service.SchoolAppender
import com.asap.asapbackend.global.util.TransactionUtils
import io.github.oshai.kotlinlogging.KotlinLogging
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Component

private val logger = KotlinLogging.logger {}

@Component
class SchoolScheduler(
private val schoolInfoProvider: SchoolInfoProvider,
private val schoolAppender: SchoolAppender
) {
@Scheduled(cron = "0 0 4 1 3 ?") // 매년 3월 1일 04:00:00에 실행
// @Scheduled(fixedRate = 500000) // 500초마다 실행
fun addSchool() {
val batchSize = 100
var startIndex = 1
logger.info { "start scheduler" }
do {
val schoolDataContainer = schoolInfoProvider.retrieveSchoolInfo(batchSize, startIndex)

Expand All @@ -27,6 +22,6 @@ class SchoolScheduler(
TransactionUtils.writable {
schoolAppender.appendUniqueSchool(schoolDataContainer.schoolInfo.toSchools())
}
}while (schoolDataContainer.hasNext)
} while (schoolDataContainer.hasNext)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.asap.asapbackend.client.openapi.classroom

import com.asap.asapbackend.batch.classroom.ClassroomInfoProvider
import com.asap.asapbackend.client.openapi.classroom.dto.ClassroomOpenApiResponse
import com.asap.asapbackend.domain.school.domain.repository.SchoolRepository
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.util.UriBuilder
import java.time.Year

@Component
class ClassroomOpenApiClient(
private val schoolRepository: SchoolRepository
) : ClassroomInfoProvider {
override fun retrieveClassroomInfo(batchSize: Int, startIndex: Int): ClassroomInfoProvider.ClassroomDataContainer {
val endIndex = startIndex + batchSize
val schools = schoolRepository.findAll().subList(startIndex, endIndex)
val classroomInfoList = mutableListOf<ClassroomInfoProvider.ClassroomInfo>()
schools.forEach { school ->
val apiUrl = "https://open.neis.go.kr/hub/classInfo"
val classroomInfoResult = WebClient.create(apiUrl).get()
.uri { uriBuilder: UriBuilder ->
uriBuilder
.queryParam("KEY", "32e897d4054342b19fd68dfb1b9ba621")
.queryParam("ATPT_OFCDC_SC_CODE", school.eduOfficeCode)
.queryParam("SD_SCHUL_CODE", school.schoolCode)
.queryParam("AY", Year.now())
.queryParam("Type", "json")
.build()
}
.retrieve()
.bodyToMono(String::class.java)
.map {
jacksonObjectMapper().readValue(it, ClassroomOpenApiResponse::class.java)
}
.block()
val classroomInfo = classroomInfoResult?.classInfo?.firstOrNull()
classroomInfo?.row?.forEach { row ->
classroomInfoList.add(row.toClassroomInfo(school))
}
}
val hasNext = schoolRepository.count() > endIndex

return ClassroomInfoProvider.ClassroomDataContainer(
classroomInfo = classroomInfoList,
hasNext = hasNext
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.asap.asapbackend.client.openapi.classroom.dto

import com.asap.asapbackend.batch.classroom.ClassroomInfoProvider
import com.asap.asapbackend.domain.school.domain.model.School

data class ClassroomOpenApiResponse(
val classInfo: List<ClassInfo>
)

data class ClassInfo(
val head: List<Head>?,
val row: List<Row>?
)

data class Head(
val list_total_count: Int?
)

data class Row(
val ATPT_OFCDC_SC_CODE: String?,
val ATPT_OFCDC_SC_NM: String?,
val SD_SCHUL_CODE: String?,
val SCHUL_NM: String?,
val AY: String?,
val GRADE: Int,
val DGHT_CRSE_SC_NM: String?,
val SCHUL_CRSE_SC_NM: String?,
val ORD_SC_NM: String?,
val DDDEP_NM: String?,
val CLASS_NM: String,
val LOAD_DTM: String?
) {
fun toClassroomInfo(school: School): ClassroomInfoProvider.ClassroomInfo {
return ClassroomInfoProvider.ClassroomInfo(
school,
GRADE,
CLASS_NM
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.client.WebClient

@Component
class SchoolOpenApiClient : SchoolInfoProvider{
override fun retrieveSchoolInfo(batchSize: Int, startIndex: Int): SchoolInfoProvider.SchoolDataContainer{
class SchoolOpenApiClient : SchoolInfoProvider {
override fun retrieveSchoolInfo(batchSize: Int, startIndex: Int): SchoolInfoProvider.SchoolDataContainer {
val endIndex = startIndex + batchSize
val apiUrl = "http://openapi.seoul.go.kr:8088/4b78477274736f6d36386d505a614b/json/neisSchoolInfoJS/$startIndex/$endIndex"
val schoolInfoResult = WebClient.create(apiUrl).get()
.retrieve()
.bodyToMono(SchoolOpenApiResponse::class.java)
.block()
val neisSchoolInfoJS = schoolInfoResult?.neisSchoolInfoJS
val hasNext = (schoolInfoResult?.neisSchoolInfoJS?.list_total_count ?: 0) > endIndex
val hasNext = (neisSchoolInfoJS?.list_total_count ?: 0) > endIndex
return SchoolInfoProvider.SchoolDataContainer(
schoolInfo = neisSchoolInfoJS?.row?.map { it.toSchoolInfo() } ?: emptyList(),
hasNext = hasNext
Expand Down
Loading

0 comments on commit de909a3

Please sign in to comment.