diff --git a/code/README.md b/code/README.md index 702ed0789d..765db25234 100644 --- a/code/README.md +++ b/code/README.md @@ -5,7 +5,7 @@ com.expediagroup rapid-sdk - 5.3.1 + 5.3.2 ``` diff --git a/code/pom.xml b/code/pom.xml index 8722edf2a9..c551f19c70 100644 --- a/code/pom.xml +++ b/code/pom.xml @@ -4,9 +4,9 @@ 4.0.0 com.expediagroup rapid-sdk - 5.3.1 + 5.3.2 EG rapid-sdk for Java - EG rapid-sdk v5.3.1 + EG rapid-sdk v5.3.2 https://github.com/ExpediaGroup/test-sdk 2022 jar @@ -72,17 +72,17 @@ 3.3.1 3.5.2 3.6.0 - 3.4.0 + 3.5.0 0.8.12 - 1.9.20 + 2.0.0 1.2.1 4.6 1.6.0 - 2.0.21 - 1.9.0 - 2.3.13 - 0.26.1 + 2.1.0 + 1.10.1 + 3.0.3 + 0.27.0 2.0.16 1.7.0 3.2.7 @@ -138,12 +138,12 @@ com.squareup.okio okio-jvm - 3.9.1 + 3.10.2 org.jetbrains annotations - 26.0.1 + 26.0.2 org.hibernate.validator @@ -449,6 +449,7 @@ org.jetbrains.dokka dokka-maven-plugin + ${dokka-plugin.version} ${project.basedir}/src/main/kotlin/com/expediagroup/sdk/rapid @@ -732,13 +733,13 @@ org.apache.commons commons-lang3 - 3.14.0 + 3.17.0 org.apache.commons commons-text - 1.12.0 + 1.13.0 diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/client/Client.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/client/Client.kt index de2847b942..d0d57c7ca0 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/client/Client.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/client/Client.kt @@ -54,7 +54,7 @@ import okhttp3.Dispatcher import okhttp3.OkHttpClient // Create a Dispatcher with limits -val dispatcher = +val configuredDispatcher = Dispatcher().apply { maxRequests = 10000 // Maximum number of concurrent requests maxRequestsPerHost = 1000 @@ -64,7 +64,7 @@ val DEFAULT_HTTP_CLIENT_ENGINE: HttpClientEngine = OkHttp.create { config { eventListenerFactory(OkHttpEventListener.FACTORY) - dispatcher(dispatcher) + dispatcher(configuredDispatcher) } } diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/client/ExpediaGroupClient.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/client/ExpediaGroupClient.kt index b47306debb..fc84287e18 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/client/ExpediaGroupClient.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/client/ExpediaGroupClient.kt @@ -67,4 +67,20 @@ abstract class ExpediaGroupClient( return self() } } + + @Suppress("unused", "UnnecessaryAbstractClass") // This is used by the generated SDK clients. + abstract class BuilderWithHttpClient> : Client.BuilderWithHttpClient() { + /** Sets the API auth endpoint to use for requests. */ + protected var authEndpoint: String? = null + + /** Sets the API auth endpoint to use for requests. + * + * @param authEndpoint The API auth endpoint to use for requests. + * @return The [Builder] instance. + */ + fun authEndpoint(authEndpoint: String): SELF { + this.authEndpoint = authEndpoint + return self() + } + } } diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/configuration/provider/XapConfigurationProvider.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/configuration/provider/XapConfigurationProvider.kt index 20857cce79..48cf654dd3 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/configuration/provider/XapConfigurationProvider.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/configuration/provider/XapConfigurationProvider.kt @@ -15,11 +15,6 @@ */ package com.expediagroup.sdk.core.configuration.provider -import com.expediagroup.sdk.core.configuration.provider.RapidConfigurationProvider.connectionTimeout -import com.expediagroup.sdk.core.configuration.provider.RapidConfigurationProvider.endpoint -import com.expediagroup.sdk.core.configuration.provider.RapidConfigurationProvider.name -import com.expediagroup.sdk.core.configuration.provider.RapidConfigurationProvider.requestTimeout -import com.expediagroup.sdk.core.configuration.provider.RapidConfigurationProvider.socketTimeout import com.expediagroup.sdk.core.constant.Constant /** diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/constant/Constant.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/constant/Constant.kt index 5f7a9d8c1d..613ee7bb22 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/constant/Constant.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/constant/Constant.kt @@ -15,13 +15,13 @@ */ package com.expediagroup.sdk.core.constant -import io.ktor.client.plugins.HttpTimeout +import io.ktor.client.plugins.HttpTimeoutConfig internal object Constant { const val EMPTY_STRING = "" const val TEN_SECONDS_IN_MILLIS = 10_000L const val FIFTEEN_SECONDS_IN_MILLIS = 15_000L - const val INFINITE_TIMEOUT = HttpTimeout.INFINITE_TIMEOUT_MS + const val INFINITE_TIMEOUT = HttpTimeoutConfig.INFINITE_TIMEOUT_MS private const val SUCCESSFUL_STATUS_CODES_RANGE_START = 200 private const val SUCCESSFUL_STATUS_CODES_RANGE_END = 299 diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/constant/LogMaskingRegex.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/constant/LogMaskingRegex.kt index 63d51c0bef..650f878493 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/constant/LogMaskingRegex.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/constant/LogMaskingRegex.kt @@ -15,8 +15,10 @@ */ package com.expediagroup.sdk.core.constant +import com.expediagroup.sdk.core.constant.LoggingMessage.OMITTED + internal object LogMaskingRegex { val FIELD_REGEX = "^[a-zA-Z0-9-_]+$".toRegex() - val NUMBER_FIELD_REGEX = "(?<=[\"']?number[\"']?:\\s?[\"'])(\\s*\\d{15,16}\\s*)(?=[\"'])".toRegex() + const val REPLACEMENT_TEMPLATE = "\"$1$2${OMITTED}\"" } diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/constant/provider/LogMaskingRegexProvider.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/constant/provider/LogMaskingRegexProvider.kt index 475e6f4c2d..9422980213 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/constant/provider/LogMaskingRegexProvider.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/constant/provider/LogMaskingRegexProvider.kt @@ -16,5 +16,19 @@ package com.expediagroup.sdk.core.constant.provider internal object LogMaskingRegexProvider { - fun getMaskedFieldsRegex(maskedBodyFields: Set) = "(?<=[\"']?(${maskedBodyFields.joinToString("|")})[\"']?:\\s?[\"'])(\\s*[^\"']+\\s*)(?=[\"'])".toRegex() + fun getMaskedFieldsRegex( + maskedBodyFields: Set, + value: String = "[^\\\"]+" + ): Regex { + val fields = maskedBodyFields.joinToString("|") + return "\"($fields)(\\\\*\"\\s*:\\s*\\\\*\")$value(?:\\\\?\"|)".toRegex() + } + + fun getMaskedFieldsRegex( + maskedBodyField: String, + value: String = "[^\\\"]+" + ): Regex { + val fields = setOf(maskedBodyField) + return getMaskedFieldsRegex(fields, value) + } } diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/model/paging/ResponseState.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/model/paging/ResponseState.kt index 19897831d8..000557f756 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/model/paging/ResponseState.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/model/paging/ResponseState.kt @@ -16,17 +16,10 @@ package com.expediagroup.sdk.core.model.paging import com.expediagroup.sdk.core.client.Client -import com.expediagroup.sdk.core.constant.HeaderValue import com.expediagroup.sdk.core.model.Response -import com.expediagroup.sdk.core.plugin.logging.GZipEncoder.decode -import com.expediagroup.sdk.core.plugin.logging.contentEncoding import io.ktor.client.statement.HttpResponse -import io.ktor.util.InternalAPI -import io.ktor.util.moveToByteArray -import io.ktor.utils.io.ByteReadChannel -import io.ktor.utils.io.bits.Memory +import io.ktor.client.statement.bodyAsBytes import kotlinx.coroutines.runBlocking -import java.nio.ByteBuffer internal interface ResponseState { fun getNextResponse(): Response @@ -63,22 +56,10 @@ internal class FetchLinkState( override fun hasNext(): Boolean = true - private suspend fun parseBody(response: HttpResponse): T = if (decodeBody(response).isEmpty()) fallbackBody else getBody(response) - - private suspend fun decodeBody(response: HttpResponse): String { - val byteReadChannel = prepareByteReadChannel(response) - val decodedByteReadChannel = if (response.contentEncoding().equals(HeaderValue.GZIP)) client.httpClient.decode(byteReadChannel) else byteReadChannel - val bodyString: String = decodedByteReadChannel.readRemaining().readText() - return bodyString - } - - @OptIn(InternalAPI::class) - private suspend fun prepareByteReadChannel(response: HttpResponse): ByteReadChannel { - val bufferSize = response.content.availableForRead - val buffer = ByteBuffer.allocate(bufferSize) - val numberOfBytesRead = response.content.peekTo(Memory(buffer), 0, 0, 0, bufferSize.toLong()).toInt() - val byteReadChannel = ByteReadChannel(buffer.moveToByteArray(), 0, numberOfBytesRead) - return byteReadChannel + private suspend fun parseBody(response: HttpResponse): T { + // response.bodyAsBytes() applies all plugins + // if content-length header is set, response.contentLength could be used instead + return if (response.bodyAsBytes().isEmpty()) fallbackBody else getBody(response) } } diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/AuthenticationStrategy.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/AuthenticationStrategy.kt index 6a44a53d49..ec5e5f5c0d 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/AuthenticationStrategy.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/AuthenticationStrategy.kt @@ -20,11 +20,11 @@ import com.expediagroup.sdk.core.plugin.authentication.AuthenticationConfigurati import com.expediagroup.sdk.core.plugin.authentication.strategy.AuthenticationStrategy.AuthenticationType.BASIC import com.expediagroup.sdk.core.plugin.authentication.strategy.AuthenticationStrategy.AuthenticationType.BEARER import com.expediagroup.sdk.core.plugin.authentication.strategy.AuthenticationStrategy.AuthenticationType.SIGNATURE -import io.ktor.client.plugins.auth.Auth +import io.ktor.client.plugins.auth.AuthConfig import io.ktor.client.request.HttpRequestBuilder internal interface AuthenticationStrategy { - fun loadAuth(auth: Auth) {} + fun loadAuth(auth: AuthConfig) {} fun isTokenAboutToExpire(): Boolean diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/BasicAuthenticationStrategy.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/BasicAuthenticationStrategy.kt index 2d87d76dfb..c6e01389db 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/BasicAuthenticationStrategy.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/BasicAuthenticationStrategy.kt @@ -16,7 +16,7 @@ package com.expediagroup.sdk.core.plugin.authentication.strategy import com.expediagroup.sdk.core.plugin.authentication.AuthenticationConfiguration -import io.ktor.client.plugins.auth.Auth +import io.ktor.client.plugins.auth.AuthConfig import io.ktor.client.plugins.auth.providers.BasicAuthCredentials import io.ktor.client.plugins.auth.providers.basic import io.ktor.client.request.HttpRequestBuilder @@ -24,8 +24,8 @@ import io.ktor.client.request.HttpRequestBuilder internal class BasicAuthenticationStrategy( private val configs: AuthenticationConfiguration ) : AuthenticationStrategy { - override fun loadAuth(auth: Auth) { - auth.basic { + override fun loadAuth(authConfig: AuthConfig) { + authConfig.basic { sendWithoutRequest { true } credentials { BasicAuthCredentials(username = configs.credentials.key, password = configs.credentials.secret) diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/ExpediaGroupAuthenticationStrategy.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/ExpediaGroupAuthenticationStrategy.kt index 1404a27bc0..33e1f806fb 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/ExpediaGroupAuthenticationStrategy.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/authentication/strategy/ExpediaGroupAuthenticationStrategy.kt @@ -28,11 +28,11 @@ import com.expediagroup.sdk.core.plugin.authentication.AuthenticationConfigurati import com.expediagroup.sdk.core.plugin.logging.ExpediaGroupLoggerFactory import io.ktor.client.HttpClient import io.ktor.client.call.body -import io.ktor.client.plugins.auth.Auth +import io.ktor.client.plugins.auth.AuthConfig +import io.ktor.client.plugins.auth.authProviders import io.ktor.client.plugins.auth.providers.BearerAuthProvider import io.ktor.client.plugins.auth.providers.BearerTokens import io.ktor.client.plugins.auth.providers.bearer -import io.ktor.client.plugins.plugin import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.basicAuth import io.ktor.client.request.parameter @@ -53,8 +53,8 @@ internal class ExpediaGroupAuthenticationStrategy( private val log = ExpediaGroupLoggerFactory.getLogger(javaClass) private var bearerTokenStorage = BearerTokensInfo.emptyBearerTokenInfo - override fun loadAuth(auth: Auth) { - auth.bearer { + override fun loadAuth(authConfig: AuthConfig) { + authConfig.bearer { sendWithoutRequest { request -> isIdentityRequest(request) } @@ -94,7 +94,7 @@ internal class ExpediaGroupAuthenticationStrategy( private fun clearTokens(client: HttpClient) { log.info(LoggingMessage.TOKEN_CLEARING_IN_PROGRESS) - client.plugin(Auth).providers.filterIsInstance().first().clearToken() + client.authProviders.filterIsInstance().first().clearToken() bearerTokenStorage = BearerTokensInfo.emptyBearerTokenInfo log.info(LoggingMessage.TOKEN_CLEARING_SUCCESSFUL) } diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldFilter.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldFilter.kt deleted file mode 100644 index 9a60c277dd..0000000000 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldFilter.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2022 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.sdk.core.plugin.logging - -import com.ebay.ejmask.core.BaseFilter - -internal class ExpediaGroupJsonFieldFilter(maskedFields: Array) : BaseFilter( - ExpediaGroupJsonFieldPatternBuilder::class.java, - *maskedFields -) diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldPatternBuilder.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldPatternBuilder.kt deleted file mode 100644 index 63ca9cfdba..0000000000 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldPatternBuilder.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2022 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.sdk.core.plugin.logging - -import com.ebay.ejmask.extenstion.builder.json.JsonFieldPatternBuilder -import com.expediagroup.sdk.core.constant.LoggingMessage.OMITTED - -internal class ExpediaGroupJsonFieldPatternBuilder : JsonFieldPatternBuilder() { - override fun buildReplacement( - visibleCharacters: Int, - vararg fieldNames: String? - ): String = "\"$1$2$OMITTED\"" -} diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupLogger.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupLogger.kt index 6390f5c7aa..31008521b3 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupLogger.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupLogger.kt @@ -21,8 +21,6 @@ import com.expediagroup.sdk.core.constant.LoggingMessage.LOGGING_PREFIX import org.slf4j.Logger internal class ExpediaGroupLogger(private val logger: Logger, private val client: Client? = null) : Logger by logger { - private val mask = LogMasker(getMaskedBodyFieldFilters()) - override fun info(msg: String) { if (logger.isInfoEnabled) { logger.info(decorate(msg)) @@ -41,12 +39,7 @@ internal class ExpediaGroupLogger(private val logger: Logger, private val client } } - private fun decorate(msg: String): String = "$LOGGING_PREFIX ${mask(msg)}" + private fun decorate(msg: String): String = "$LOGGING_PREFIX ${mask(msg, getMaskedBodyFields())}" private fun getMaskedBodyFields(): Set = client?.getLoggingMaskedFieldsProvider()?.getMaskedBodyFields() ?: LogMaskingFields.DEFAULT_MASKED_BODY_FIELDS - - private fun getMaskedBodyFieldFilters(): Iterable = - listOf( - ExpediaGroupJsonFieldFilter(getMaskedBodyFields().toTypedArray()) - ) } diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LogMasker.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LogMasker.kt index 36628610f8..526fbc9ea5 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LogMasker.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LogMasker.kt @@ -15,18 +15,24 @@ */ package com.expediagroup.sdk.core.plugin.logging -import com.ebay.ejmask.core.BaseFilter -import com.ebay.ejmask.core.EJMask -import com.ebay.ejmask.core.EJMaskInitializer -import com.ebay.ejmask.core.util.LoggerUtil +import com.expediagroup.sdk.core.constant.LogMaskingRegex.REPLACEMENT_TEMPLATE +import com.expediagroup.sdk.core.constant.provider.LogMaskingRegexProvider -internal class LogMasker( - filters: Iterable -) : (String) -> String { - init { - LoggerUtil.register { _, _, _ -> /* disable logging */ } - filters.forEach { EJMaskInitializer.addFilter(it) } - } +internal fun mask( + message: String, + maskedBodyFields: Set +): String { + val masks: List = + listOf( + Mask { LogMaskingRegexProvider.getMaskedFieldsRegex(maskedBodyFields) }, + Mask { LogMaskingRegexProvider.getMaskedFieldsRegex("number", "\\d{12,19}") } + ) - override fun invoke(message: String): String = EJMask.mask(message) + return masks.fold(message) { acc, mask -> mask.mask(acc) } +} + +internal fun interface Mask { + fun getRegex(): Regex + + fun mask(string: String) = string.replace(this.getRegex(), REPLACEMENT_TEMPLATE) } diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LoggingConfiguration.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LoggingConfiguration.kt index cd34324a95..70787421b8 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LoggingConfiguration.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LoggingConfiguration.kt @@ -26,7 +26,7 @@ internal data class LoggingConfiguration( override val httpClientConfiguration: HttpClientConfig, val maskedLoggingHeaders: Set, val maskedLoggingBodyFields: Set, - val level: LogLevel = LogLevel.HEADERS, + val level: LogLevel = LogLevel.ALL, val getLogger: (client: Client) -> Logger = createCustomLogger ) : KtorPluginConfiguration(httpClientConfiguration) { companion object { diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LoggingPlugin.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LoggingPlugin.kt index 758a5df725..b27483e324 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LoggingPlugin.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/LoggingPlugin.kt @@ -41,8 +41,6 @@ internal object LoggingPlugin : Plugin { client.getLoggingMaskedFieldsProvider().getMaskedHeaderFields().contains(header) } } - configurations.httpClientConfiguration.install(RequestBodyLogger) - configurations.httpClientConfiguration.install(ResponseBodyLogger) } } diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/RequestBodyLogger.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/RequestBodyLogger.kt deleted file mode 100644 index 5a077a148e..0000000000 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/RequestBodyLogger.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2022 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.sdk.core.plugin.logging - -import com.expediagroup.sdk.core.constant.LoggerName -import com.expediagroup.sdk.core.constant.provider.LoggingMessageProvider -import com.expediagroup.sdk.core.model.getTransactionId -import io.ktor.client.HttpClient -import io.ktor.client.plugins.HttpClientPlugin -import io.ktor.client.request.HttpRequestBuilder -import io.ktor.client.request.HttpSendPipeline -import io.ktor.http.content.OutputStreamContent -import io.ktor.http.contentType -import io.ktor.util.AttributeKey -import io.ktor.util.pipeline.PipelineContext -import io.ktor.utils.io.writer -import kotlinx.coroutines.coroutineScope - -internal class RequestBodyLogger { - private val log = ExpediaGroupLoggerFactory.getLogger(javaClass) - - companion object Plugin : HttpClientPlugin { - override val key: AttributeKey = AttributeKey(LoggerName.REQUEST_BODY_LOGGER) - - override fun install( - plugin: RequestBodyLogger, - scope: HttpClient - ) { - scope.sendPipeline.intercept(HttpSendPipeline.Monitoring) { - val body: String = getBody() - plugin.log.debug(LoggingMessageProvider.getRequestBodyMessage(body, context.headers.getTransactionId())) - proceed() - } - } - - private suspend fun PipelineContext.getBody(): String { - val body = - when { - context.contentType() in LoggableContentTypes -> context.body - else -> return "Body of type ${context.contentType()?.contentType} cannot be logged!" - } - - if (body is OutputStreamContent) { - return coroutineScope { - writer { - body.writeTo(channel) - }.channel.readRemaining().readText() - } - } - return body.toString() - } - - override fun prepare(block: RequestBodyLoggerConfig.() -> Unit): RequestBodyLogger = RequestBodyLogger() - } -} - -internal class RequestBodyLoggerConfig diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ResponseBodyLogger.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ResponseBodyLogger.kt deleted file mode 100644 index c06f8fdc7f..0000000000 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ResponseBodyLogger.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2022 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.sdk.core.plugin.logging - -import com.expediagroup.sdk.core.constant.HeaderValue -import com.expediagroup.sdk.core.constant.LoggerName -import com.expediagroup.sdk.core.constant.provider.LoggingMessageProvider -import com.expediagroup.sdk.core.model.getTransactionId -import com.expediagroup.sdk.core.plugin.logging.GZipEncoder.decode -import io.ktor.client.HttpClient -import io.ktor.client.plugins.HttpClientPlugin -import io.ktor.client.plugins.compression.ContentEncoder -import io.ktor.client.statement.HttpResponse -import io.ktor.client.statement.HttpResponsePipeline -import io.ktor.client.statement.request -import io.ktor.http.HttpHeaders -import io.ktor.http.contentType -import io.ktor.util.AttributeKey -import io.ktor.util.Encoder -import io.ktor.util.GZip -import io.ktor.util.InternalAPI -import io.ktor.utils.io.ByteReadChannel - -class ResponseBodyLogger { - private val log = ExpediaGroupLoggerFactory.getLogger(javaClass) - - companion object Plugin : HttpClientPlugin { - override val key: AttributeKey = AttributeKey(LoggerName.RESPONSE_BODY_LOGGER) - - @OptIn(InternalAPI::class) - override fun install( - plugin: ResponseBodyLogger, - scope: HttpClient - ) { - scope.responsePipeline.intercept(HttpResponsePipeline.Receive) { - val response: HttpResponse = context.response - val byteReadChannel: ByteReadChannel = if (response.contentEncoding().equals(HeaderValue.GZIP)) scope.decode(response.content) else response.content - - when { - response.contentType() in LoggableContentTypes -> - LoggingMessageProvider.getResponseBodyMessage( - byteReadChannel.readRemaining().readText(), - response.request.headers.getTransactionId() - ) - else -> LoggingMessageProvider.getResponseBodyMessage("Body of type ${response.contentType()?.contentType} cannot be logged!", response.request.headers.getTransactionId()) - }.let { - plugin.log.debug(it) - } - - proceed() - } - } - - override fun prepare(block: ResponseBodyLoggerConfig.() -> Unit): ResponseBodyLogger = ResponseBodyLogger() - } -} - -fun HttpResponse.contentEncoding(): String? = headers[HttpHeaders.ContentEncoding] - -internal object GZipEncoder : ContentEncoder, Encoder by GZip { - override val name: String = HeaderValue.GZIP -} - -class ResponseBodyLoggerConfig