Add HMS Oauth services and DTO's

This commit is contained in:
Korna 2022-11-07 18:19:50 +03:00
parent 5b3c7ed4b7
commit f387dac898
5 changed files with 136 additions and 0 deletions

View File

@ -0,0 +1,11 @@
package ru.touchin.push.message.provider.hpk.services
import ru.touchin.push.message.provider.hpk.services.dto.AccessToken
interface HmsOauthAccessTokenCacheService {
fun put(accessToken: AccessToken)
fun get(): AccessToken?
fun evict()
}

View File

@ -0,0 +1,73 @@
package ru.touchin.push.message.provider.hpk.services
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.cache.Cache
import org.springframework.cache.CacheManager
import org.springframework.stereotype.Service
import ru.touchin.push.message.provider.hpk.properties.HpkProperties
import ru.touchin.push.message.provider.hpk.services.dto.AccessToken
import java.time.Instant
@Service
class HmsOauthAccessTokenCacheServiceImpl(
@Qualifier("push-message-provider.hpk.webclient-cachemanager")
private val cacheManager: CacheManager,
@Qualifier("push-message-provider.hpk.client-objectmapper")
private val objectMapper: ObjectMapper,
private val hpkProperties: HpkProperties,
) : HmsOauthAccessTokenCacheService {
override fun put(accessToken: AccessToken) {
getCache()?.put(hpkProperties.webServices.clientId, accessToken)
}
override fun get(): AccessToken? { // TODO: implement synchronization for all threads
val cachedValue = getCache()
?.get(hpkProperties.webServices.clientId)
?.get()
?: return null
val accessToken = safeCast(cachedValue, object : TypeReference<AccessToken>() {})
?: return null
return if (accessToken.isValid()) {
accessToken
} else {
null
}
}
override fun evict() {
getCache()?.evict(hpkProperties.webServices.clientId)
}
private fun <T> safeCast(item: Any, typeReference: TypeReference<T>): T? {
return try {
objectMapper.convertValue(item, typeReference)
} catch (e: Exception) {
print(e.message)
null
}
}
private fun AccessToken.isValid(): Boolean {
val expirationTime = with(hpkProperties.webServices.oauth) {
Instant.now().plus(http.connectionTimeout + http.readTimeout + http.writeTimeout)
}
return expiresAt.isAfter(expirationTime)
}
private fun getCache(): Cache? {
return cacheManager.getCache(HMS_CLIENT_SERVICE_CACHE_KEY)
}
companion object {
const val HMS_CLIENT_SERVICE_CACHE_KEY = "HMS_CLIENT_SERVICE"
}
}

View File

@ -0,0 +1,7 @@
package ru.touchin.push.message.provider.hpk.services
interface HmsOauthClientService {
fun getAccessToken(): String
}

View File

@ -0,0 +1,37 @@
package ru.touchin.push.message.provider.hpk.services
import org.springframework.stereotype.Service
import ru.touchin.push.message.provider.exceptions.PushMessageProviderException
import ru.touchin.push.message.provider.hpk.clients.hms_oauth.HmsOauthWebClient
import ru.touchin.push.message.provider.hpk.services.dto.AccessToken
import java.time.Instant
@Service
class HmsOauthClientServiceImpl(
private val hmsOauthAccessTokenCacheService: HmsOauthAccessTokenCacheService,
private val hmsOauthWebClient: HmsOauthWebClient,
) : HmsOauthClientService {
override fun getAccessToken(): String {
val accessToken = hmsOauthAccessTokenCacheService.get()
?: retrieveAccessToken().also(hmsOauthAccessTokenCacheService::put)
return accessToken.value
}
private fun retrieveAccessToken(): AccessToken {
val result = hmsOauthWebClient.token()
if (result.success == null) {
throw PushMessageProviderException(result.failure?.errorDescription.orEmpty(), null)
}
return with(result.success) {
AccessToken(
value = accessToken,
expiresAt = Instant.now().plusSeconds(expiresIn)
)
}
}
}

View File

@ -0,0 +1,8 @@
package ru.touchin.push.message.provider.hpk.services.dto
import java.time.Instant
data class AccessToken(
val value: String,
val expiresAt: Instant,
)