diff --git a/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/clients/FcmClient.kt b/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/clients/FcmClient.kt index ec51bbe..126df6b 100644 --- a/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/clients/FcmClient.kt +++ b/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/clients/FcmClient.kt @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component import ru.touchin.push.message.provider.dto.request.PushTokenCheck import ru.touchin.push.message.provider.dto.request.PushTokenMessage import ru.touchin.push.message.provider.dto.result.SendPushResult -import ru.touchin.push.message.provider.dto.result.SendPushTokenMessageResult +import ru.touchin.push.message.provider.dto.result.SendPushTokenMessageTraceableResult import ru.touchin.push.message.provider.enums.PushTokenStatus import ru.touchin.push.message.provider.exceptions.InvalidPushTokenException import ru.touchin.push.message.provider.exceptions.PushMessageProviderException @@ -32,7 +32,7 @@ class FcmClient( fun check(request: PushTokenCheck): PushTokenStatus { val validationRequest = PushTokenMessage( token = request.pushToken, - notification = null, + pushMessageNotification = null, data = emptyMap() ) @@ -54,7 +54,7 @@ class FcmClient( return try { val messageId = firebaseMessaging.send(message, dryRun) - SendPushTokenMessageResult(messageId) + SendPushTokenMessageTraceableResult(messageId) } catch (e: FirebaseMessagingException) { throw firebaseMessagingExceptionConverter(e) } diff --git a/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/NotificationConverter.kt b/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/NotificationConverter.kt deleted file mode 100644 index cfd40bc..0000000 --- a/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/NotificationConverter.kt +++ /dev/null @@ -1,18 +0,0 @@ -package ru.touchin.push.message.provider.fcm.converters - -import com.google.firebase.messaging.Notification as FcmNotification -import org.springframework.stereotype.Component -import ru.touchin.push.message.provider.dto.Notification - -@Component -class NotificationConverter { - - operator fun invoke(notification: Notification): FcmNotification { - return FcmNotification.builder() - .setTitle(notification.title) - .setBody(notification.description) - .setImage(notification.imageUrl) - .build() - } - -} diff --git a/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/PushMessageNotificationConverter.kt b/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/PushMessageNotificationConverter.kt new file mode 100644 index 0000000..6e53c31 --- /dev/null +++ b/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/PushMessageNotificationConverter.kt @@ -0,0 +1,18 @@ +package ru.touchin.push.message.provider.fcm.converters + +import com.google.firebase.messaging.Notification as FcmNotification +import org.springframework.stereotype.Component +import ru.touchin.push.message.provider.dto.PushMessageNotification + +@Component +class PushMessageNotificationConverter { + + operator fun invoke(pushMessageNotification: PushMessageNotification): FcmNotification { + return FcmNotification.builder() + .setTitle(pushMessageNotification.title) + .setBody(pushMessageNotification.description) + .setImage(pushMessageNotification.imageUrl) + .build() + } + +} diff --git a/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/PushTokenMessageConverter.kt b/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/PushTokenMessageConverter.kt index 43fc415..16f0847 100644 --- a/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/PushTokenMessageConverter.kt +++ b/push-message-provider-fcm/src/main/kotlin/ru/touchin/push/message/provider/fcm/converters/PushTokenMessageConverter.kt @@ -6,12 +6,12 @@ import com.google.firebase.messaging.ApnsConfig import com.google.firebase.messaging.Aps import com.google.firebase.messaging.Message import org.springframework.stereotype.Component -import ru.touchin.push.message.provider.dto.Notification +import ru.touchin.push.message.provider.dto.PushMessageNotification import ru.touchin.push.message.provider.dto.request.PushTokenMessage @Component class PushTokenMessageConverter( - private val notificationConverter: NotificationConverter + private val pushMessageNotificationConverter: PushMessageNotificationConverter ) { private companion object { @@ -26,14 +26,14 @@ class PushTokenMessageConverter( .setToken(request.token) .setupApns() .setupAndroid() - .setIfExists(request.notification) + .setIfExists(request.pushMessageNotification) .putAllData(request.data) .build() } - private fun Message.Builder.setIfExists(notification: Notification?): Message.Builder { - return if (notification != null) { - setNotification(notificationConverter(notification)) + private fun Message.Builder.setIfExists(pushMessageNotification: PushMessageNotification?): Message.Builder { + return if (pushMessageNotification != null) { + setNotification(pushMessageNotificationConverter(pushMessageNotification)) } else { this } diff --git a/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/NotificationConverterTest.kt b/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/PushMessageNotificationConverterTest.kt similarity index 69% rename from push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/NotificationConverterTest.kt rename to push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/PushMessageNotificationConverterTest.kt index a15c159..6ecb019 100644 --- a/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/NotificationConverterTest.kt +++ b/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/PushMessageNotificationConverterTest.kt @@ -5,15 +5,15 @@ import org.junit.Assert import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest -import ru.touchin.push.message.provider.dto.Notification +import ru.touchin.push.message.provider.dto.PushMessageNotification import com.google.firebase.messaging.Notification as FcmNotification import org.junit.jupiter.api.DisplayName @SpringBootTest -class NotificationConverterTest { +class PushMessageNotificationConverterTest { @Autowired - lateinit var notificationConverter: NotificationConverter + lateinit var pushMessageNotificationConverter: PushMessageNotificationConverter @Autowired lateinit var objectMapper: ObjectMapper @@ -21,19 +21,19 @@ class NotificationConverterTest { @Test @DisplayName("Конвертация уведомления происходит корректно") fun invoke_basic() { - val notification = Notification( + val pushMessageNotification = PushMessageNotification( title = "title", description = "description", imageUrl = "imageUrl" ) - val realResult = notificationConverter(notification) + val realResult = pushMessageNotificationConverter(pushMessageNotification) val realResultJson = objectMapper.writeValueAsString(realResult) val expectedResult = FcmNotification.builder() - .setTitle(notification.title) - .setBody(notification.description) - .setImage(notification.imageUrl) + .setTitle(pushMessageNotification.title) + .setBody(pushMessageNotification.description) + .setImage(pushMessageNotification.imageUrl) .build() val expectedResultJson = objectMapper.writeValueAsString(expectedResult) diff --git a/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/PushTokenMessageConverterTest.kt b/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/PushTokenMessageConverterTest.kt index bcd0954..0ed8888 100644 --- a/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/PushTokenMessageConverterTest.kt +++ b/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/converters/PushTokenMessageConverterTest.kt @@ -11,7 +11,7 @@ import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest -import ru.touchin.push.message.provider.dto.Notification +import ru.touchin.push.message.provider.dto.PushMessageNotification import ru.touchin.push.message.provider.dto.request.PushTokenMessage @SpringBootTest @@ -21,7 +21,7 @@ class PushTokenMessageConverterTest { lateinit var pushTokenMessageConverter: PushTokenMessageConverter @Autowired - lateinit var notificationConverter: NotificationConverter + lateinit var pushMessageNotificationConverter: PushMessageNotificationConverter @Autowired lateinit var objectMapper: ObjectMapper @@ -29,14 +29,14 @@ class PushTokenMessageConverterTest { @Test @DisplayName("Конвертация сообщения с уведомлением происходит корректно") fun invoke_withNotification() { - val notification = Notification( + val pushMessageNotification = PushMessageNotification( title = "title", description = "description", imageUrl = "imageUrl" ) val pushTokenMessage = PushTokenMessage( token = "token", - notification = notification, + pushMessageNotification = pushMessageNotification, data = mapOf("testKey" to "testvalue") ) @@ -45,7 +45,7 @@ class PushTokenMessageConverterTest { val expectedResult = Message.builder() .setToken(pushTokenMessage.token) - .setNotification(notificationConverter(notification)) + .setNotification(pushMessageNotificationConverter(pushMessageNotification)) .putAllData(pushTokenMessage.data) .setupApns() .setupAndroid() @@ -65,7 +65,7 @@ class PushTokenMessageConverterTest { fun invoke_withoutNotification() { val pushTokenMessage = PushTokenMessage( token = "token", - notification = null, + pushMessageNotification = null, data = mapOf("testKey" to "testvalue") ) diff --git a/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/services/PushMessageProviderFcmServiceTest.kt b/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/services/PushMessageProviderFcmServiceTest.kt index c502fa6..32d41a9 100644 --- a/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/services/PushMessageProviderFcmServiceTest.kt +++ b/push-message-provider-fcm/src/test/kotlin/ru/touchin/push/message/provider/fcm/services/PushMessageProviderFcmServiceTest.kt @@ -10,7 +10,7 @@ import org.springframework.boot.test.mock.mockito.MockBean import ru.touchin.push.message.provider.dto.request.PushTokenCheck import ru.touchin.push.message.provider.dto.request.PushTokenMessage import ru.touchin.push.message.provider.dto.result.CheckPushTokenResult -import ru.touchin.push.message.provider.dto.result.SendPushTokenMessageResult +import ru.touchin.push.message.provider.dto.result.SendPushTokenMessageTraceableResult import ru.touchin.push.message.provider.enums.PushTokenStatus import ru.touchin.push.message.provider.fcm.clients.FcmClient import ru.touchin.push.message.provider.services.PushMessageProviderService @@ -29,11 +29,11 @@ class PushMessageProviderFcmServiceTest { fun send_basic() { val request = PushTokenMessage( token = "testToken", - notification = null, + pushMessageNotification = null, data = emptyMap() ) - val expectedResult = SendPushTokenMessageResult("testMessageId") + val expectedResult = SendPushTokenMessageTraceableResult("testMessageId") Mockito.`when`( fcmClient.sendPushTokenMessage(request) diff --git a/push-message-provider-hpk/build.gradle.kts b/push-message-provider-hpk/build.gradle.kts new file mode 100644 index 0000000..b2bcd23 --- /dev/null +++ b/push-message-provider-hpk/build.gradle.kts @@ -0,0 +1,21 @@ +plugins { + id("kotlin") + id("kotlin-spring") + id("maven-publish") +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") + + implementation("org.springframework.boot:spring-boot-starter-webflux") + + implementation(project(":logger-spring")) + implementation(project(":common-spring-web")) + implementation(project(":push-message-provider")) + + testImplementation(project(":logger-spring-web")) + + testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin") + testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.testcontainers:junit-jupiter") +} diff --git a/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/EnablePushMessageProviderHpk.kt b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/EnablePushMessageProviderHpk.kt new file mode 100644 index 0000000..a1cb474 --- /dev/null +++ b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/EnablePushMessageProviderHpk.kt @@ -0,0 +1,7 @@ +package ru.touchin.push.message.provider.hpk + +import org.springframework.context.annotation.Import +import ru.touchin.push.message.provider.hpk.configurations.PushMessageProviderHpkConfiguration + +@Import(value = [PushMessageProviderHpkConfiguration::class]) +annotation class EnablePushMessageProviderHpk diff --git a/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/builders/Buildable.kt b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/builders/Buildable.kt new file mode 100644 index 0000000..a7c1910 --- /dev/null +++ b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/builders/Buildable.kt @@ -0,0 +1,3 @@ +package ru.touchin.push.message.provider.hpk.base.builders + +internal interface Buildable diff --git a/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/clients/ConditionalWebClientParser.kt b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/clients/ConditionalWebClientParser.kt new file mode 100644 index 0000000..d1d3063 --- /dev/null +++ b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/clients/ConditionalWebClientParser.kt @@ -0,0 +1,42 @@ +package ru.touchin.push.message.provider.hpk.base.clients + +import com.fasterxml.jackson.databind.ObjectMapper +import org.springframework.web.reactive.function.client.ClientResponse +import ru.touchin.push.message.provider.hpk.base.clients.dto.ConditionalResponse + +internal open class ConditionalWebClientParser( + private val objectMapper: ObjectMapper, +) { + + open fun isOkResponse(clientResponse: ClientResponse): Boolean { + return clientResponse.statusCode().is2xxSuccessful + } + + @Throws(Exception::class) + inline fun parse( + clientResponse: ClientResponse, + body: String, + ): ConditionalResponse { + return if (isOkResponse(clientResponse)) { + ConditionalResponse( + success = parseValue(body, S::class.java), + failure = null + ) + } else { + ConditionalResponse( + success = null, + failure = parseValue(body, F::class.java) + ) + } + } + + private fun parseValue(source: String?, clazz: Class): T { + return if (clazz.canonicalName != String::class.java.canonicalName) { + objectMapper.readValue(source, clazz) + } else { + @Suppress("UNCHECKED_CAST") + source as T // T is String + } + } + +} diff --git a/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/clients/ConfigurableWebClient.kt b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/clients/ConfigurableWebClient.kt new file mode 100644 index 0000000..f2df3d3 --- /dev/null +++ b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/clients/ConfigurableWebClient.kt @@ -0,0 +1,85 @@ +package ru.touchin.push.message.provider.hpk.base.clients + +import io.netty.channel.ChannelOption +import io.netty.handler.ssl.SslContextBuilder +import io.netty.handler.timeout.ReadTimeoutHandler +import io.netty.handler.timeout.WriteTimeoutHandler +import org.springframework.http.client.reactive.ReactorClientHttpConnector +import org.springframework.web.reactive.function.client.ClientResponse +import org.springframework.web.reactive.function.client.WebClient +import reactor.core.publisher.Mono +import reactor.core.scheduler.Schedulers +import reactor.netty.http.client.HttpClient +import ru.touchin.common.spring.web.webclient.BaseLogWebClient +import ru.touchin.common.spring.web.webclient.dto.RequestLogData +import ru.touchin.common.spring.web.webclient.logger.WebClientLogger +import ru.touchin.push.message.provider.hpk.base.clients.dto.ConditionalResponse +import ru.touchin.push.message.provider.hpk.properties.HpkProperties +import java.util.concurrent.TimeUnit + +abstract class ConfigurableWebClient( + webClientLogger: WebClientLogger, + webClientBuilder: WebClient.Builder, + protected val webService: HpkProperties.WebService, +) : BaseLogWebClient(webClientLogger, webClientBuilder) { + + private val conditionalWebClientParser: Lazy = lazy { + ConditionalWebClientParser( + objectMapper = getObjectMapper(), + ) + } + + protected fun WebClient.Builder.setTimeouts(): WebClient.Builder { + val httpClient: HttpClient = HttpClient.create() + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, webService.http.connectionTimeout.toMillis().toInt()) + .doOnConnected { setup -> + setup.addHandlerLast(ReadTimeoutHandler(webService.http.readTimeout.toMillis(), TimeUnit.MILLISECONDS)) + setup.addHandlerLast(WriteTimeoutHandler(webService.http.writeTimeout.toMillis(), TimeUnit.MILLISECONDS)) + } + .let { httpClient -> + webService.ssl?.let { ssl -> + httpClient.secure { builder -> + builder + .sslContext(SslContextBuilder.forClient().build()) + .handshakeTimeout(ssl.handshakeTimeout) + .closeNotifyFlushTimeout(ssl.notifyFlushTimeout) + .closeNotifyReadTimeout(ssl.notifyReadTimeout) + } + } ?: httpClient + } + + return clientConnector(ReactorClientHttpConnector(httpClient)) + } + + internal inline fun WebClient.RequestHeadersSpec<*>.exchangeWithWrap( + requestLogData: RequestLogData, + ): Mono> { + return exchangeToMono { clientResponse -> + parse(clientResponse) + }.doOnNext { responseWrapper -> + getLogger().log( + requestLogData.copy( + responseBody = responseWrapper.success ?: responseWrapper.failure + ) + ) + } + } + + internal inline fun parse( + clientResponse: ClientResponse, + ): Mono> { + val responseBody = clientResponse + .bodyToMono(String::class.java) + .defaultIfEmpty(String()) + .publishOn(Schedulers.parallel()) + + return responseBody + .map { body -> + conditionalWebClientParser.value.parse( + clientResponse = clientResponse, + body = body, + ) + } + } + +} diff --git a/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/clients/dto/ConditionalResponse.kt b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/clients/dto/ConditionalResponse.kt new file mode 100644 index 0000000..ee865b8 --- /dev/null +++ b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/clients/dto/ConditionalResponse.kt @@ -0,0 +1,15 @@ +package ru.touchin.push.message.provider.hpk.base.clients.dto + +internal open class ConditionalResponse( + val success: S?, + val failure: F?, +) { + + init { + // Only one value should be present + check((success == null) != (failure == null)) + } + + val isSuccess: Boolean = success != null + +} diff --git a/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/enums/ValueableSerializableEnum.kt b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/enums/ValueableSerializableEnum.kt new file mode 100644 index 0000000..388d0c9 --- /dev/null +++ b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/enums/ValueableSerializableEnum.kt @@ -0,0 +1,12 @@ +package ru.touchin.push.message.provider.hpk.base.enums + +import com.fasterxml.jackson.annotation.JsonValue + +internal interface ValueableSerializableEnum { + + val value: T + + @JsonValue + fun toValue(): T = value + +} diff --git a/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/extensions/BuilderExtensions.kt b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/extensions/BuilderExtensions.kt new file mode 100644 index 0000000..fb00d9c --- /dev/null +++ b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/base/extensions/BuilderExtensions.kt @@ -0,0 +1,7 @@ +package ru.touchin.push.message.provider.hpk.base.extensions + +import ru.touchin.push.message.provider.hpk.base.builders.Buildable + +fun B.ifNotNull(value: V?, setter: B.(V) -> B): B { + return value?.let { setter(it) } ?: this +} diff --git a/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/configurations/PushMessageProviderHpkConfiguration.kt b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/configurations/PushMessageProviderHpkConfiguration.kt new file mode 100644 index 0000000..f5a5567 --- /dev/null +++ b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/configurations/PushMessageProviderHpkConfiguration.kt @@ -0,0 +1,59 @@ +package ru.touchin.push.message.provider.hpk.configurations + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.boot.context.properties.ConfigurationPropertiesScan +import org.springframework.cache.CacheManager +import org.springframework.cache.concurrent.ConcurrentMapCache +import org.springframework.cache.support.SimpleCacheManager +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Import +import ru.touchin.push.message.provider.configurations.PushMessageProviderConfiguration +import ru.touchin.push.message.provider.hpk.services.HmsOauthAccessTokenCacheServiceImpl.Companion.HMS_CLIENT_SERVICE_CACHE_KEY + +@ComponentScan("ru.touchin.push.message.provider.hpk") +@ConfigurationPropertiesScan(basePackages = ["ru.touchin.push.message.provider.hpk"]) +@Import(value = [PushMessageProviderConfiguration::class]) +class PushMessageProviderHpkConfiguration { + + @Bean + @Qualifier("push-message-provider.hpk.webclient-objectmapper") + fun webclientObjectMapper(): ObjectMapper { + return jacksonObjectMapper() + .registerModule(JavaTimeModule()) + .setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) + .setSerializationInclusion(JsonInclude.Include.NON_NULL) + .setSerializationInclusion(JsonInclude.Include.NON_EMPTY) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + } + + @Bean + @Qualifier("push-message-provider.hpk.client-objectmapper") + fun clientObjectMapper(): ObjectMapper { + return jacksonObjectMapper() + .registerModule(JavaTimeModule()) + .setSerializationInclusion(JsonInclude.Include.NON_NULL) + .setSerializationInclusion(JsonInclude.Include.NON_EMPTY) + } + + @Bean + @ConditionalOnMissingBean + @Qualifier("push-message-provider.hpk.webclient-cachemanager") + fun cacheManager(): CacheManager { + return SimpleCacheManager().also { + it.setCaches( + listOf( + ConcurrentMapCache(HMS_CLIENT_SERVICE_CACHE_KEY) + ) + ) + } + } + +} diff --git a/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/properties/HpkProperties.kt b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/properties/HpkProperties.kt new file mode 100644 index 0000000..3dd6d33 --- /dev/null +++ b/push-message-provider-hpk/src/main/kotlin/ru/touchin/push/message/provider/hpk/properties/HpkProperties.kt @@ -0,0 +1,59 @@ +package ru.touchin.push.message.provider.hpk.properties + +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.boot.context.properties.ConstructorBinding +import java.net.URL +import java.time.Duration + +@ConstructorBinding +@ConfigurationProperties(prefix = "push-message-provider.hpk") +data class HpkProperties( + val webServices: WebServices, +) { + + class WebServices( + val clientId: String, + val oauth: Oauth, + val hpk: Hpk, + ) + + class Oauth( + val clientSecret: String, + url: URL, + http: Http, + ssl: Ssl?, + ) : WebService( + url = url, + http = http, + ssl = ssl, + ) + + class Hpk( + url: URL, + http: Http, + ssl: Ssl?, + ) : WebService( + url = url, + http = http, + ssl = ssl, + ) + + open class WebService( + val url: URL, + val http: Http, + val ssl: Ssl?, + ) + + class Http( + val readTimeout: Duration, + val writeTimeout: Duration, + val connectionTimeout: Duration, + ) + + class Ssl( + val handshakeTimeout: Duration, + val notifyFlushTimeout: Duration, + val notifyReadTimeout: Duration, + ) + +} diff --git a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/Notification.kt b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/PushMessageNotification.kt similarity index 80% rename from push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/Notification.kt rename to push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/PushMessageNotification.kt index 0b10a0a..8605533 100644 --- a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/Notification.kt +++ b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/PushMessageNotification.kt @@ -1,6 +1,6 @@ package ru.touchin.push.message.provider.dto -class Notification( +class PushMessageNotification( val title: String?, val description: String?, val imageUrl: String? diff --git a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/request/PushTokenMessage.kt b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/request/PushTokenMessage.kt index 56b73a8..84f355e 100644 --- a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/request/PushTokenMessage.kt +++ b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/request/PushTokenMessage.kt @@ -1,9 +1,9 @@ package ru.touchin.push.message.provider.dto.request -import ru.touchin.push.message.provider.dto.Notification +import ru.touchin.push.message.provider.dto.PushMessageNotification class PushTokenMessage( val token: String, - override val notification: Notification?, + override val pushMessageNotification: PushMessageNotification?, override val data: Map ) : SendPushRequest diff --git a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/request/SendPushRequest.kt b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/request/SendPushRequest.kt index 0bdaf3f..2e50d82 100644 --- a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/request/SendPushRequest.kt +++ b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/request/SendPushRequest.kt @@ -1,10 +1,10 @@ package ru.touchin.push.message.provider.dto.request -import ru.touchin.push.message.provider.dto.Notification +import ru.touchin.push.message.provider.dto.PushMessageNotification sealed interface SendPushRequest { - val notification: Notification? + val pushMessageNotification: PushMessageNotification? val data: Map } diff --git a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/CheckPushTokenResult.kt b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/CheckPushTokenResult.kt index e8ddd4b..a746ce0 100644 --- a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/CheckPushTokenResult.kt +++ b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/CheckPushTokenResult.kt @@ -3,5 +3,5 @@ package ru.touchin.push.message.provider.dto.result import ru.touchin.push.message.provider.enums.PushTokenStatus data class CheckPushTokenResult( - val status: PushTokenStatus + val status: PushTokenStatus, ) diff --git a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/SendPushTokenMessageResult.kt b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/SendPushTokenMessageResult.kt index c5047fa..95f1d86 100644 --- a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/SendPushTokenMessageResult.kt +++ b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/SendPushTokenMessageResult.kt @@ -1,5 +1,3 @@ package ru.touchin.push.message.provider.dto.result -class SendPushTokenMessageResult( - val messageId: String -) : SendPushResult +object SendPushTokenMessageResult : SendPushResult diff --git a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/SendPushTokenMessageTraceableResult.kt b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/SendPushTokenMessageTraceableResult.kt new file mode 100644 index 0000000..273962d --- /dev/null +++ b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/dto/result/SendPushTokenMessageTraceableResult.kt @@ -0,0 +1,5 @@ +package ru.touchin.push.message.provider.dto.result + +data class SendPushTokenMessageTraceableResult( + val messageId: String +) : SendPushResult diff --git a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/enums/PlatformType.kt b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/enums/PlatformType.kt index d88f8ea..f03a082 100644 --- a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/enums/PlatformType.kt +++ b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/enums/PlatformType.kt @@ -3,6 +3,7 @@ package ru.touchin.push.message.provider.enums enum class PlatformType { ANDROID_GOOGLE, + ANDROID_HUAWEI, IOS } diff --git a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/enums/PushMessageProviderType.kt b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/enums/PushMessageProviderType.kt index 3999187..cd8aa96 100644 --- a/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/enums/PushMessageProviderType.kt +++ b/push-message-provider/src/main/kotlin/ru/touchin/push/message/provider/enums/PushMessageProviderType.kt @@ -2,6 +2,7 @@ package ru.touchin.push.message.provider.enums enum class PushMessageProviderType { - FCM + FCM, + HPK, } diff --git a/settings.gradle.kts b/settings.gradle.kts index 6ddd481..e2d5daf 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -45,6 +45,7 @@ include("validation-spring") include("version-spring-web") include("push-message-provider") include("push-message-provider-fcm") +include("push-message-provider-hpk") include("response-wrapper-spring-web") include("settings-spring-jpa") include("security-authorization-server-core")