feat(CON-167) : [SDK] - Mettre en place la récupération des données sur le BO

This commit is contained in:
Louis Legrand 2024-12-11 09:15:11 +01:00
parent 2b9bfe3c5b
commit 01704d7191
9 changed files with 269 additions and 3 deletions

View File

@ -3,6 +3,7 @@ plugins {
alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.android)
alias(libs.plugins.hilt) alias(libs.plugins.hilt)
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
alias(libs.plugins.serialization)
} }
android { android {
@ -43,6 +44,22 @@ dependencies {
implementation(libs.hilt.android) implementation(libs.hilt.android)
ksp(libs.hilt.compiler) ksp(libs.hilt.compiler)
// Serialization
implementation(libs.serializationJson)
// Retrofit
api(libs.retrofit)
implementation(libs.retrofitConverter)
implementation(libs.logging.interceptor)
// OkHttp
api(libs.okhttp)
implementation(platform(libs.okhttp.bom))
implementation(libs.okhttp)
// Timber
implementation(libs.timber)
// Test // Test
testImplementation(libs.test.junit) testImplementation(libs.test.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)

View File

@ -0,0 +1,37 @@
package fr.openium.consentium
import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import fr.openium.consentium.data.di.ConsentiumUrl
import fr.openium.consentium.data.di.NetworkModule
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import timber.log.Timber
@Module
@InstallIn(SingletonComponent::class)
class DebugNetworkModule {
@Provides
fun provideOkHttpBuilder(
@ApplicationContext context: Context,
): OkHttpClient.Builder =
NetworkModule.standardOkHttpBuilder(context)
.addNetworkInterceptor(HttpLoggingInterceptor { message ->
Timber.tag("OkHttp")
Timber.v(message)
}.apply {
level = HttpLoggingInterceptor.Level.BODY
})
@ConsentiumUrl
@Provides
fun okHttpUrlConsentium(@ApplicationContext context: Context): HttpUrl =
context.getString(R.string.backend_url).toHttpUrl()
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="backend_url" translatable="false" tools:ignore="UnusedResources">https://consentium-api-dev.openium.fr/api/v1/app</string>
</resources>

View File

@ -0,0 +1,78 @@
package fr.openium.consentium.data.di
import android.content.Context
import dagger.Lazy
import dagger.Module
import dagger.Provides
import dagger.Reusable
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import fr.openium.consentium.data.remote.ConsentiumApi
import kotlinx.serialization.json.Json
import okhttp3.Cache
import okhttp3.HttpUrl
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.kotlinx.serialization.asConverterFactory
import java.util.concurrent.TimeUnit
import javax.inject.Qualifier
import javax.inject.Singleton
private val json by lazy {
Json {
isLenient = true
ignoreUnknownKeys = true
}
}
@Module
@InstallIn(SingletonComponent::class)
internal object NetworkModule {
@OkHttpClientDefault
@Provides
@Singleton
fun okHttpClientDefault(
okHttpBuilder: OkHttpClient.Builder,
): OkHttpClient = okHttpBuilder.build()
fun standardOkHttpBuilder(
context: Context,
): OkHttpClient.Builder {
val cacheSize = (20 * 1024 * 1024).toLong() // 20 MiB
val cache = Cache(context.cacheDir, cacheSize)
return OkHttpClient.Builder()
.cache(cache)
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
}
@Reusable
@Provides
fun provideConsentiumApi(
@ConsentiumUrl url: HttpUrl,
@OkHttpClientDefault okHttpClient: Lazy<OkHttpClient>,
): ConsentiumApi =
createRetrofit(
url,
okHttpClient
).create(ConsentiumApi::class.java)
private fun createRetrofit(url: HttpUrl, okHttpClient: Lazy<OkHttpClient>): Retrofit =
Retrofit.Builder()
.callFactory { request ->
okHttpClient.get().newCall(request)
}.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.baseUrl(url)
.build()
}
@Qualifier
@Retention(AnnotationRetention.BINARY)
internal annotation class ConsentiumUrl
@Qualifier
@Retention(AnnotationRetention.BINARY)
internal annotation class OkHttpClientDefault

View File

@ -0,0 +1,25 @@
package fr.openium.consentium.data.remote
import fr.openium.consentium.data.remote.model.GetConsent
import fr.openium.consentium.data.remote.model.PatchConsent
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.PATCH
internal interface ConsentiumApi {
@GET("/consents")
suspend fun getConsents(
applicationId: String,
installationId: String,
): GetConsent.GetConsentPayloadDTO
@PATCH("/consents")
suspend fun setConsents(
applicationId: String,
installationId: String,
@Body patchConsent: PatchConsent.PatchConsentPayloadDTO,
): Any
}

View File

@ -0,0 +1,44 @@
package fr.openium.consentium.data.remote.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
internal sealed interface GetConsent {
@Serializable
data class GetConsentPayloadDTO(
@SerialName("installationId") val installationId: String,
@SerialName("purposes") val purposes: List<PurposeDTO>? = null,
@SerialName("isValid") val isValid: Boolean,
)
@Serializable
data class PurposeDTO(
@SerialName("identifier") val identifier: String,
@SerialName("isRequired") val isRequired: Boolean,
@SerialName("isAccepted") val isAccepted: PurposeStatus,
@SerialName("vendors") val vendors: List<VendorDTO>? = null,
)
@Serializable
data class VendorDTO(
@SerialName("identifier") val identifier: String,
@SerialName("isRequired") val isRequired: Boolean,
@SerialName("isAccepted") val isAccepted: Boolean,
)
@Serializable
enum class PurposeStatus {
@SerialName("ACCEPTED")
ACCEPTED,
@SerialName("REJECTED")
REJECTED,
@SerialName("NOT_DEFINED")
NOT_DEFINED,
}
}

View File

@ -0,0 +1,27 @@
package fr.openium.consentium.data.remote.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
internal sealed interface PatchConsent {
@Serializable
data class PatchConsentPayloadDTO(
@SerialName("installationId") val installationId: String,
@SerialName("purposes") val purposes: List<PurposeDTO>? = null,
)
@Serializable
data class PurposeDTO(
@SerialName("identifier") val identifier: String,
@SerialName("isAccepted") val isAccepted: Boolean,
@SerialName("vendors") val vendors: List<VendorDTO>? = null,
)
@Serializable
data class VendorDTO(
@SerialName("identifier") val identifier: String,
@SerialName("isAccepted") val isAccepted: Boolean,
)
}

View File

@ -0,0 +1,13 @@
package fr.openium.consentium.data.repository
import fr.openium.consentium.data.local.ConsentiumDataStore
import fr.openium.consentium.data.remote.ConsentiumApi
import javax.inject.Inject
internal class ConsentiumRepository @Inject constructor(
private val consentiumApi: ConsentiumApi,
private val consentiumDataStore: ConsentiumDataStore,
) {
}

View File

@ -26,6 +26,17 @@ timber = "5.0.1"
# Material # Material
material = "1.12.0" material = "1.12.0"
# Serialization
serialization = "2.0.21"
jsonSerialization = "1.7.3"
# Retrofit
retrofit = "2.11.0"
loggingInterceptor = "4.12.0"
# Okhttp
okhttpBom = "4.12.0"
# Test # Test
junit = "4.13.2" junit = "4.13.2"
espressoCore = "3.6.1" espressoCore = "3.6.1"
@ -94,6 +105,18 @@ androidx-navigation-compose = { group = "androidx.navigation", name = "navigatio
# Preferences DataStore # Preferences DataStore
preferencesDataStore = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "preferencesDataStore" } preferencesDataStore = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "preferencesDataStore" }
# Json serialization
serializationJson = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "jsonSerialization" }
# Retrofit
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
retrofitConverter = { group = "com.squareup.retrofit2", name = "converter-kotlinx-serialization", version.ref = "retrofit" }
logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "loggingInterceptor" }
# Okhttp
okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttpBom" }
okhttp = { module = "com.squareup.okhttp3:okhttp" }
# Test # Test
test-junit = { group = "junit", name = "junit", version.ref = "junit" } test-junit = { group = "junit", name = "junit", version.ref = "junit" }
test-androidx-junit = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "junitExtVersion" } test-androidx-junit = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "junitExtVersion" }
@ -107,9 +130,7 @@ kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "ko
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
android-library = { id = "com.android.library", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "serialization" }
[bundles] [bundles]
androidx = ["androidx-core-ktx", "androidx-activity-compose"] androidx = ["androidx-core-ktx", "androidx-activity-compose"]