Skip to content

Commit 7ced140

Browse files
authored
release: 2.2.9 (#408)
2 parents 1a09e7c + f714470 commit 7ced140

File tree

8 files changed

+149
-20
lines changed

8 files changed

+149
-20
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.gitanimals.rank.app
2+
3+
import java.time.LocalDate
4+
5+
fun interface RankContributionApi {
6+
7+
fun getContributionsBySpecificDays(username: String, from: LocalDate, to: LocalDate): Int
8+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.gitanimals.rank.app
2+
3+
import org.gitanimals.rank.domain.UserContributionRank
4+
import org.gitanimals.rank.domain.UserContributionRankService
5+
import org.slf4j.LoggerFactory
6+
import org.springframework.stereotype.Component
7+
import java.time.LocalDate
8+
import java.time.temporal.WeekFields
9+
import java.util.*
10+
11+
@Component
12+
class UpdateUserContributionFacade(
13+
private val identityApi: IdentityApi,
14+
private val rankContributionApi: RankContributionApi,
15+
private val userContributionRankService: UserContributionRankService,
16+
) {
17+
18+
private val logger = LoggerFactory.getLogger(this::class.simpleName)
19+
20+
fun updateUserWeeklyContributions(username: String) {
21+
val user = identityApi.getUserByName(username)
22+
23+
val from = LocalDate.now().with(WeekFields.of(Locale.getDefault()).dayOfWeek(), 1)
24+
val to = LocalDate.now().with(WeekFields.of(Locale.getDefault()).dayOfWeek(), 7)
25+
26+
val weeklyContributions = rankContributionApi.getContributionsBySpecificDays(
27+
username = username,
28+
from = from,
29+
to = to,
30+
)
31+
32+
val updatedUserContributionRank = UserContributionRank.create(
33+
image = user.profileImage,
34+
userId = user.id.toLong(),
35+
username = user.username,
36+
weeklyContributions = weeklyContributions.toLong(),
37+
)
38+
39+
userContributionRankService.updateContribution(updatedUserContributionRank)
40+
logger.info("[UpdateUserContributionFacade] update user weekly contributions. username: \"$username\", updated contributions: $weeklyContributions")
41+
}
42+
}

src/main/kotlin/org/gitanimals/rank/domain/UserContributionRankService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class UserContributionRankService(
1919
fun updateContribution(updateUserContributionRank: UserContributionRank) {
2020
val userRank = runCatching {
2121
userContributionRankRepository.findByUserId(updateUserContributionRank.userId)?.also {
22-
it.weeklyContributions += updateUserContributionRank.weeklyContributions
22+
it.weeklyContributions = updateUserContributionRank.weeklyContributions
2323
}
2424
?: throw IllegalArgumentException("Cannot find UserContributionRank by userId: \"${updateUserContributionRank.userId}\"")
2525
}.getOrElse {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package org.gitanimals.rank.infra.github
2+
3+
import org.gitanimals.rank.app.RankContributionApi
4+
import org.springframework.beans.factory.annotation.Value
5+
import org.springframework.core.io.ClassPathResource
6+
import org.springframework.http.HttpHeaders
7+
import org.springframework.stereotype.Component
8+
import org.springframework.web.client.RestClient
9+
import java.nio.charset.Charset
10+
import java.time.LocalDate
11+
import java.util.concurrent.Executors
12+
13+
@Component
14+
class RankGithubContributionApi(
15+
@Value("\${github.token}") private val token: String
16+
) : RankContributionApi {
17+
18+
private val restClient = RestClient.create("https://api.github.com/graphql")
19+
private val executors = Executors.newFixedThreadPool(50)
20+
21+
override fun getContributionsBySpecificDays(username: String, from: LocalDate, to: LocalDate): Int {
22+
val fromString = from.toString()
23+
val toString = from.toString()
24+
25+
return restClient.post()
26+
.header(HttpHeaders.AUTHORIZATION, "Bearer $token")
27+
.body(
28+
mapOf(
29+
"query" to contributionCountByYearAndWeekQuery
30+
.replaceFirst(NAME_FIX, username)
31+
.replaceFirst(DATE_START_FIX, fromString)
32+
.replaceFirst(DATE_END_FIX, toString)
33+
)
34+
).exchange { _, response ->
35+
assertIsSuccess(response)
36+
37+
response.bodyTo(ContributionCountByYearAndWeekQueryResponse::class.java)!!
38+
.data
39+
.user
40+
.contributionsCollection
41+
.contributionCalendar
42+
.totalContributions
43+
}
44+
}
45+
46+
private fun assertIsSuccess(response: RestClient.RequestHeadersSpec.ConvertibleClientHttpResponse) {
47+
require(response.statusCode.is2xxSuccessful) {
48+
"Bad request cause status : \"${response.statusText}\" message : \"${
49+
response.bodyTo(
50+
String::class.java
51+
)
52+
}\""
53+
}
54+
}
55+
56+
private data class ContributionCountByYearAndWeekQueryResponse(val data: Data) {
57+
class Data(val user: User) {
58+
class User(val contributionsCollection: ContributionsCollection) {
59+
class ContributionsCollection(
60+
val contributionCalendar: ContributionCalendar,
61+
) {
62+
class ContributionCalendar(
63+
val totalContributions: Int,
64+
)
65+
}
66+
}
67+
68+
}
69+
}
70+
71+
companion object {
72+
private const val NAME_FIX = "*{name}"
73+
private const val DATE_START_FIX = "*{yyyy-mm-dd-start}"
74+
private const val DATE_END_FIX = "*{yyyy-mm-dd-end}"
75+
76+
private val contributionCountByYearAndWeekQuery =
77+
ClassPathResource("github-graphql/contribution-count-by-year-and-week.graphql")
78+
.getContentAsString(Charset.defaultCharset())
79+
}
80+
}

src/main/kotlin/org/gitanimals/rank/infra/RankRedisEventSubscriber.kt renamed to src/main/kotlin/org/gitanimals/rank/infra/listener/RankRedisEventSubscriber.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.gitanimals.rank.infra
1+
package org.gitanimals.rank.infra.listener
22

33
import org.gitanimals.core.redis.RedisPubSubChannel
44
import org.springframework.context.annotation.Bean

src/main/kotlin/org/gitanimals/rank/infra/RankUpdateGuildContributionMessageListener.kt renamed to src/main/kotlin/org/gitanimals/rank/infra/listener/RankUpdateGuildContributionMessageListener.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.gitanimals.rank.infra
1+
package org.gitanimals.rank.infra.listener
22

33
import com.fasterxml.jackson.databind.ObjectMapper
44
import org.gitanimals.core.redis.TraceableMessageListener

src/main/kotlin/org/gitanimals/rank/infra/UpdateUserContributionMessageListener.kt renamed to src/main/kotlin/org/gitanimals/rank/infra/listener/UpdateUserContributionMessageListener.kt

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
package org.gitanimals.rank.infra
1+
package org.gitanimals.rank.infra.listener
22

33
import com.fasterxml.jackson.databind.ObjectMapper
44
import org.gitanimals.core.redis.TraceableMessageListener
5-
import org.gitanimals.rank.app.IdentityApi
6-
import org.gitanimals.rank.domain.UserContributionRank
7-
import org.gitanimals.rank.domain.UserContributionRankService
5+
import org.gitanimals.rank.app.UpdateUserContributionFacade
86
import org.gitanimals.rank.infra.event.UserContributionUpdated
97
import org.slf4j.LoggerFactory
108
import org.springframework.beans.factory.annotation.Qualifier
@@ -14,10 +12,9 @@ import org.springframework.stereotype.Component
1412

1513
@Component
1614
class UpdateUserContributionMessageListener(
17-
private val identityApi: IdentityApi,
1815
private val objectMapper: ObjectMapper,
19-
private val userContributionRankService: UserContributionRankService,
2016
@Qualifier("gitanimalsRedisTemplate") private val redisTemplate: StringRedisTemplate,
17+
private val updateUserContributionFacade: UpdateUserContributionFacade,
2118
) : TraceableMessageListener(
2219
listenerName = "UpdateUserContributionMessageListener",
2320
objectMapper = objectMapper,
@@ -33,18 +30,11 @@ class UpdateUserContributionMessageListener(
3330
UserContributionUpdated::class.java,
3431
)
3532

36-
val updatedUserContributionRank = runCatching {
37-
val user = identityApi.getUserByName(userContributionUpdated.username)
33+
if (userContributionUpdated.updatedContributions == 0L) {
34+
return
35+
}
3836

39-
UserContributionRank.create(
40-
image = user.profileImage,
41-
userId = user.id.toLong(),
42-
username = user.username,
43-
weeklyContributions = userContributionUpdated.updatedContributions,
44-
)
45-
}.getOrElse { return }
46-
47-
userContributionRankService.updateContribution(updatedUserContributionRank)
37+
updateUserContributionFacade.updateUserWeeklyContributions(userContributionUpdated.username)
4838
}.onFailure {
4939
logger.error("Cannot update user contributions rank by message: $message", it)
5040
throw it
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
query {
2+
user(login: "*{name}") {
3+
contributionsCollection(from: "*{yyyy-mm-dd-start}T00:00:00Z", to: "*{yyyy-mm-dd-end}T23:59:59Z") {
4+
contributionCalendar {
5+
totalContributions
6+
}
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)