From 3051d43b8ffcff6b34440365012b40567fd01743 Mon Sep 17 00:00:00 2001 From: vityaman Date: Fri, 14 Jun 2024 11:43:29 +0300 Subject: [PATCH] #139 Send published homeworks to telegram --- .../spring/api/http/endpoint/RatingHttpApi.kt | 1 - ...r.kt => SpringKafkaPublicationConsumer.kt} | 3 ++- .../app/spring/task/SpringNotificationTask.kt | 17 ++++++------- .../spring/task/SpringPublicationConfig.kt | 8 ++++++ .../app/spring/task/SpringPublicationTask.kt | 1 + .../task/SpringTelegramPublicationConsumer.kt | 19 ++++++++++++++ .../external/telegram/BasicTelegramBot.kt | 2 +- .../telegram/TelegramPublicationConsumer.kt | 25 +++++++++++++++++++ .../botalka/storage/kafka/KafkaProducer.kt | 1 - infra/fuzzing/custom/homeworks.sh | 2 +- 10 files changed, 64 insertions(+), 15 deletions(-) rename botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/{SpringPublicationConsumer.kt => SpringKafkaPublicationConsumer.kt} (89%) create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationConfig.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringTelegramPublicationConsumer.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/publication/telegram/TelegramPublicationConsumer.kt diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/RatingHttpApi.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/RatingHttpApi.kt index 3e7656f..510ee62 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/RatingHttpApi.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/RatingHttpApi.kt @@ -19,7 +19,6 @@ class RatingHttpApi( ResponseEntity.ok( RatingGrades( grades = service.grades().map { (student, grades) -> - println("$student $grades") StudentGradesMessage( studentId = student.id.number, grades = grades.entries diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationConsumer.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringKafkaPublicationConsumer.kt similarity index 89% rename from botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationConsumer.kt rename to botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringKafkaPublicationConsumer.kt index 50d6abe..c965137 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationConsumer.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringKafkaPublicationConsumer.kt @@ -10,7 +10,8 @@ import ru.vityaman.lms.botalka.storage.kafka.KafkaProducer import ru.vityaman.lms.botalka.storage.kafka.KafkaTopic @Component -class SpringPublicationConsumer( +@Qualifier(SpringPublicationConfig.BeanName.KAFKA_CONSUMER) +class SpringKafkaPublicationConsumer( @Value("\${broker.bootstrap-servers}") bootstrapServers: String, diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringNotificationTask.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringNotificationTask.kt index e4f5248..78a35a3 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringNotificationTask.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringNotificationTask.kt @@ -1,12 +1,12 @@ package ru.vityaman.lms.botalka.app.spring.task import kotlinx.coroutines.runBlocking +import org.springframework.beans.factory.annotation.Qualifier import org.springframework.beans.factory.annotation.Value import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component -import ru.vityaman.lms.botalka.commons.Consumer import ru.vityaman.lms.botalka.core.logging.Slf4jLog -import ru.vityaman.lms.botalka.core.model.Homework +import ru.vityaman.lms.botalka.core.publication.PublicationConsumer import ru.vityaman.lms.botalka.core.publication.PublicationSupplier import ru.vityaman.lms.botalka.core.publication.logging.loggingNotificationCallbacks import ru.vityaman.lms.botalka.core.publication.task.NotificationTask @@ -19,20 +19,17 @@ class SpringNotificationTask( batchDurationSeconds: Int, supplier: PublicationSupplier, -) { - private val log = Slf4jLog("NotificationTask") + @Qualifier(SpringPublicationConfig.BeanName.TELEGRAM_CONSUMER) + consumer: PublicationConsumer, +) { private val logic = NotificationTask( supplier = supplier, - consumer = object : Consumer { - override suspend fun accept(value: Homework) { - log.info("Consumed $value") - } - }, + consumer = consumer, config = NotificationTask.Config( batchDuration = batchDurationSeconds.seconds, ), - callbacks = loggingNotificationCallbacks(log), + callbacks = loggingNotificationCallbacks(Slf4jLog("NotificationTask")), ) @Scheduled( diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationConfig.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationConfig.kt new file mode 100644 index 0000000..6a6a0b2 --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationConfig.kt @@ -0,0 +1,8 @@ +package ru.vityaman.lms.botalka.app.spring.task + +class SpringPublicationConfig { + object BeanName { + const val KAFKA_CONSUMER = "kafkaPublicationConsumer" + const val TELEGRAM_CONSUMER = "telegramPublicationConsumer" + } +} diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationTask.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationTask.kt index 4169752..a316139 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationTask.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringPublicationTask.kt @@ -18,6 +18,7 @@ import java.util.concurrent.TimeUnit class SpringPublicationTask( homeworks: HomeworkStorage, + @Qualifier(SpringPublicationConfig.BeanName.KAFKA_CONSUMER) consumer: PublicationConsumer, @Qualifier(MainR2dbcConfig.BeanName.TX_ENV) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringTelegramPublicationConsumer.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringTelegramPublicationConsumer.kt new file mode 100644 index 0000000..774f1a6 --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/task/SpringTelegramPublicationConsumer.kt @@ -0,0 +1,19 @@ +package ru.vityaman.lms.botalka.app.spring.task + +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.beans.factory.annotation.Value +import org.springframework.stereotype.Component +import ru.vityaman.lms.botalka.core.external.telegram.TelegramBot +import ru.vityaman.lms.botalka.core.external.telegram.TelegramChat +import ru.vityaman.lms.botalka.core.publication.PublicationConsumer +import ru.vityaman.lms.botalka.core.publication.telegram.TelegramPublicationConsumer + +@Component +@Qualifier(SpringPublicationConfig.BeanName.TELEGRAM_CONSUMER) +class SpringTelegramPublicationConsumer( + telegram: TelegramBot, + + @Value("\${external.service.telegram.admin-chat-id}") + adminChatId: Long, +) : PublicationConsumer by +TelegramPublicationConsumer(telegram, TelegramChat(adminChatId)) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/external/telegram/BasicTelegramBot.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/external/telegram/BasicTelegramBot.kt index 267b71d..80f994b 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/external/telegram/BasicTelegramBot.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/external/telegram/BasicTelegramBot.kt @@ -30,7 +30,7 @@ class BasicTelegramBot(accessToken: String) : TelegramBot { override suspend fun send(chat: TelegramChat, message: TelegramMessage) { withContext(Dispatchers.IO) { - bot.sendMessage(ChatId.fromId(chat.id), text = message.text) + bot.sendMessage(ChatId.fromId(chat.id), text = message.text).get() } } diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/publication/telegram/TelegramPublicationConsumer.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/publication/telegram/TelegramPublicationConsumer.kt new file mode 100644 index 0000000..c804d2e --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/publication/telegram/TelegramPublicationConsumer.kt @@ -0,0 +1,25 @@ +package ru.vityaman.lms.botalka.core.publication.telegram + +import ru.vityaman.lms.botalka.core.external.telegram.TelegramBot +import ru.vityaman.lms.botalka.core.external.telegram.TelegramChat +import ru.vityaman.lms.botalka.core.external.telegram.TelegramMessage +import ru.vityaman.lms.botalka.core.model.Homework +import ru.vityaman.lms.botalka.core.publication.PublicationConsumer + +class TelegramPublicationConsumer( + private val telegram: TelegramBot, + private val adminChat: TelegramChat, +) : PublicationConsumer { + override suspend fun accept(value: Homework) { + val text = buildString { + append("Published homework '${value.title.text}'!\n") + append("\n") + append("${value.description}\n") + append("\n") + append("MaxScore: ${value.maxScore.value}\n") + append("Deadline: ${value.deadlineMoment}\n") + append("Id: ${value.id.number}\n") + } + telegram.send(adminChat, TelegramMessage(text)) + } +} diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/storage/kafka/KafkaProducer.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/storage/kafka/KafkaProducer.kt index cac37ed..ba1a2b0 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/storage/kafka/KafkaProducer.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/storage/kafka/KafkaProducer.kt @@ -34,7 +34,6 @@ class KafkaProducer( .let { SenderRecord.create(it, null) } .let { mono { it } } kafka.send(record).asFlow().collect {} - println("Sent $value") } data class Config( diff --git a/infra/fuzzing/custom/homeworks.sh b/infra/fuzzing/custom/homeworks.sh index c55dc81..8c4e1f8 100755 --- a/infra/fuzzing/custom/homeworks.sh +++ b/infra/fuzzing/custom/homeworks.sh @@ -8,7 +8,7 @@ MOMENT="$2" echo "[fuzz] Got access token: '$TOKEN'" echo "[fuzz] Got moment: '$MOMENT'" -for _ in $(seq 1 128); do +for _ in $(seq 1 32); do curl -X 'POST' \ 'http://localhost:8080/api/v1/homework' \ -H 'accept: application/json' \