Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added HttpLogger as a configuration for FhirEngine. #1570

Merged
merged 21 commits into from
Oct 4, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added HttpLogger as a configuration for FhirEngine
  • Loading branch information
aditya-07 committed Aug 24, 2022
commit 27d5713826353a841b06e724a7a8a789795e4cf9
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Google LLC
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@ import com.google.android.fhir.FhirEngineProvider
import com.google.android.fhir.ServerConfiguration
import com.google.android.fhir.demo.data.FhirPeriodicSyncWorker
import com.google.android.fhir.sync.Sync
import com.google.android.fhir.sync.remote.HttpLogger
import timber.log.Timber

class FhirApplication : Application() {
Expand All @@ -40,7 +41,15 @@ class FhirApplication : Application() {
FhirEngineConfiguration(
enableEncryptionIfSupported = true,
RECREATE_AT_OPEN,
ServerConfiguration("https://hapi.fhir.org/baseR4/")
ServerConfiguration(
"https://hapi.fhir.org/baseR4/",
httpLogger =
HttpLogger(
HttpLogger.Configuration(
if (BuildConfig.DEBUG) HttpLogger.Level.BODY else HttpLogger.Level.BASIC
)
) { Timber.tag("App-HttpLog").d(it) }
)
)
)
Sync.oneTimeSync<FhirPeriodicSyncWorker>(this)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Google LLC
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,6 +20,7 @@ import android.content.Context
import com.google.android.fhir.DatabaseErrorStrategy.UNSPECIFIED
import com.google.android.fhir.sync.Authenticator
import com.google.android.fhir.sync.DataSource
import com.google.android.fhir.sync.remote.HttpLogger

/** The provider for [FhirEngine] instance. */
object FhirEngineProvider {
Expand Down Expand Up @@ -124,13 +125,15 @@ enum class DatabaseErrorStrategy {
}

/**
* A configuration to provide the remote FHIR server url and an [Authenticator] for supplying any
* auth token that may be necessary to communicate with the server.
* A configuration to provide the remote FHIR server url, an [Authenticator] for supplying any auth
aditya-07 marked this conversation as resolved.
Show resolved Hide resolved
* token that may be necessary to communicate with the server and a [HttpLogger] to log the
* communication between the engine and the remote server.
*/
data class ServerConfiguration(
val baseUrl: String,
val networkConfiguration: NetworkConfiguration = NetworkConfiguration(),
val authenticator: Authenticator? = null
val authenticator: Authenticator? = null,
val httpLogger: HttpLogger = HttpLogger.DEFAULT
aditya-07 marked this conversation as resolved.
Show resolved Hide resolved
)

/** A configuration to provide the network connection parameters. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Google LLC
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -71,7 +71,10 @@ internal data class FhirServices(
val remoteDataSource =
serverConfiguration?.let {
RemoteFhirService.builder(it.baseUrl, it.networkConfiguration)
.apply { setAuthenticator(it.authenticator) }
.apply {
aditya-07 marked this conversation as resolved.
Show resolved Hide resolved
setAuthenticator(it.authenticator)
setHttpLogger(it.httpLogger)
}
.build()
}
return FhirServices(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2022 Google LLC
*
* 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:https://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.google.android.fhir.sync.remote

import androidx.annotation.WorkerThread
import timber.log.Timber

/** Logger for the network communication between the engine and the remote server */
class HttpLogger(val configuration: Configuration, @WorkerThread val log: (String) -> Unit) {
aditya-07 marked this conversation as resolved.
Show resolved Hide resolved

data class Configuration(
val level: Level,
/** Http headers to be ignored for the logging purpose. */
val headersToIgnore: List<String>? = null
)

/** Different levels to specify the content to be logged. */
enum class Level {
/** Nothing will be logged. */
NONE,
/** Request and response lines will logged. */
aditya-07 marked this conversation as resolved.
Show resolved Hide resolved
BASIC,
/** Lines along with the headers will logged for the request and response. */
HEADERS,
/** Lines, headers and body (if present) will be logged for the request and response. */
BODY
}

companion object {
/** The logger will not log any data. */
val NONE = HttpLogger(Configuration(Level.NONE)) {}

/** The logger will only log [Level.BASIC] data onto the system logger. */
val DEFAULT = HttpLogger(Configuration(Level.BASIC)) { Timber.tag("FHIR-Http-Logger").d(it) }
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Google LLC
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,7 +16,6 @@

package com.google.android.fhir.sync.remote

import com.google.android.fhir.BuildConfig
import com.google.android.fhir.NetworkConfiguration
import com.google.android.fhir.sync.Authenticator
import com.google.android.fhir.sync.DataSource
Expand Down Expand Up @@ -45,23 +44,36 @@ internal interface RemoteFhirService : DataSource {
private val networkConfiguration: NetworkConfiguration
) {
private var authenticator: Authenticator? = null
private var httpLoggingInterceptor: HttpLoggingInterceptor? = null

fun setAuthenticator(authenticator: Authenticator?) {
this.authenticator = authenticator
}

fun setHttpLogger(httpLogger: HttpLogger) {
httpLoggingInterceptor =
HttpLoggingInterceptor { httpLogger.log(it) }.apply {
aditya-07 marked this conversation as resolved.
Show resolved Hide resolved
level = httpLogger.configuration.level.toOkhttpLogLevel()
httpLogger.configuration.headersToIgnore?.forEach { this.redactHeader(it) }
}
}

private fun HttpLogger.Level.toOkhttpLogLevel() =
when (this) {
HttpLogger.Level.NONE -> HttpLoggingInterceptor.Level.NONE
HttpLogger.Level.HEADERS -> HttpLoggingInterceptor.Level.HEADERS
HttpLogger.Level.BASIC -> HttpLoggingInterceptor.Level.BASIC
HttpLogger.Level.BODY -> HttpLoggingInterceptor.Level.BODY
}

fun build(): RemoteFhirService {
val logger = HttpLoggingInterceptor()
logger.level =
if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY
else HttpLoggingInterceptor.Level.BASIC
val client =
OkHttpClient.Builder()
.apply {
connectTimeout(networkConfiguration.connectionTimeOut, TimeUnit.SECONDS)
readTimeout(networkConfiguration.readTimeOut, TimeUnit.SECONDS)
writeTimeout(networkConfiguration.writeTimeOut, TimeUnit.SECONDS)
addInterceptor(logger)
httpLoggingInterceptor?.let { addInterceptor(it) }
authenticator?.let {
addInterceptor(
Interceptor { chain: Interceptor.Chain ->
Expand Down