Skip to content

Commit

Permalink
Merge pull request #24 from crobox/bugfix/request-body-encoding
Browse files Browse the repository at this point in the history
Bugfix: Fixed Retrofit encoding for post request body
Add custom UUID json deserializer
Upgrade minSdk to 26
Renamed Experiments as Campaigns for clarity
  • Loading branch information
toztemel committed Jul 11, 2024
2 parents 2bf8f4c + 7b1c9fc commit 5529f04
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 128 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ android {

defaultConfig {
applicationId "com.crobox.sdk.testapp"
minSdk 22
minSdk 26
targetSdk 34
versionCode 1
versionName "1.0"
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/kotlin/com/crobox/sdk/testapp/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ class MainActivity : AppCompatActivity() {
val TAG = "PromotionCallback"

override fun onPromotions(response: PromotionsResponse?) {
val experiments: List<String>? =
response?.context?.experiments?.map { experiment ->
"Experiment[Id: ${experiment.id}, Name: ${experiment.name}]"
val campaigns: List<String>? =
response?.context?.campaigns?.map { campaign ->
"Campaign[Id: ${campaign.id}, Name: ${campaign.name}]"
}

Log.d(
Expand All @@ -126,7 +126,7 @@ class MainActivity : AppCompatActivity() {
Context [
VisitorId: ${response?.context?.visitorId}
SessionId: ${response?.context?.sessionId}
Experiments: ${experiments?.joinToString()}
Campaigns: ${campaigns?.joinToString()}
]
""".trimIndent()
)
Expand Down
2 changes: 1 addition & 1 deletion sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ android {
compileSdk 34

defaultConfig {
minSdk 22
minSdk 26
targetSdk 34
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
Expand Down
3 changes: 2 additions & 1 deletion sdk/src/main/kotlin/com/crobox/sdk/data/api/CroboxAPI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.crobox.sdk.data.api

import com.crobox.sdk.domain.BaseResponse
import com.crobox.sdk.domain.PromotionsResponse
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.http.*

Expand All @@ -11,7 +12,7 @@ internal interface CroboxAPI {
@POST("/promotions")
fun promotions(
@QueryMap options: Map<String, String>,
@Body impressions: String
@Body impressions: RequestBody
): Call<PromotionsResponse?>?

@GET("/socket.gif")
Expand Down
35 changes: 12 additions & 23 deletions sdk/src/main/kotlin/com/crobox/sdk/data/api/CroboxAPIClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,32 @@ package com.crobox.sdk.data.api
import com.crobox.sdk.domain.Constant
import com.google.gson.GsonBuilder
import com.google.gson.Strictness
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.UUID
import java.util.concurrent.TimeUnit


internal object CroboxAPIClient {
val clientWithOutToken: Retrofit
get() {
val client: OkHttpClient = client()

val gson = GsonBuilder()
.setStrictness(Strictness.LENIENT)
.disableHtmlEscaping()
.enableComplexMapKeySerialization()
.create()
val gson =
GsonBuilder()
.setStrictness(Strictness.LENIENT)
.disableHtmlEscaping()
.enableComplexMapKeySerialization()
.registerTypeAdapter(UUID::class.java, CustomUUIDDeserializer())
.create()

return Retrofit.Builder()
.client(client)
.baseUrl(Constant.API_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
return Retrofit.Builder().client(client).baseUrl(Constant.API_URL)
.addConverterFactory(GsonConverterFactory.create(gson)).build()
}

private fun client(): OkHttpClient {
val client: OkHttpClient = OkHttpClient.Builder()
.readTimeout(60 * 5, TimeUnit.SECONDS)
.connectTimeout(60 * 5, TimeUnit.SECONDS)
.addInterceptor(
Interceptor { chain: Interceptor.Chain ->
var request: Request.Builder = chain.request().newBuilder()
request = request.method(chain.request().method, chain.request().body)
chain.proceed(request.build())
}).build()
val client: OkHttpClient = OkHttpClient.Builder().readTimeout(60 * 5, TimeUnit.SECONDS)
.connectTimeout(60 * 5, TimeUnit.SECONDS).build()

return client

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.crobox.sdk.data.api

import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import java.lang.reflect.Type
import java.nio.ByteBuffer
import java.util.Base64
import java.util.UUID

internal class CustomUUIDDeserializer : JsonDeserializer<UUID> {

override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): UUID {
val uuidEncoded = json?.asString
return uuidEncoded?.let {
if (it.length == 36) {
UUID.fromString(uuidEncoded)
} else {
val bb = ByteBuffer.wrap(Base64.getUrlDecoder().decode(uuidEncoded))
UUID(bb.getLong(), bb.getLong())
}
} ?: UUID.randomUUID()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ package com.crobox.sdk.domain
import com.google.gson.annotations.SerializedName

/**
* Represents an ongoing campaign
* Represents an ongoing Campaign
*
* @property id Campaign ID
* @property name Campaign Name
* @property variantId Id of the Campaign Variant
* @property variantName Name of the Campaign Variant
* @property control Indicates if variant is allocated to the control group
*/
class Experiment {
class Campaign {
@SerializedName("id") val id: String? = null
@SerializedName("name") val name: String? = null
@SerializedName("variantId")val variantId: String? = null
Expand Down
18 changes: 13 additions & 5 deletions sdk/src/main/kotlin/com/crobox/sdk/domain/PromotionContext.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package com.crobox.sdk.domain

import com.google.gson.annotations.SerializedName
import java.util.UUID

/**
* The context about campaigns
*
* @property experiments The list of ongoing campaigns
* @property campaigns The list of ongoing campaigns
* @property sessionId Session ID
* @property visitorId Visitor ID
* @property groupName List of campaign and variant names, combined
*
*/
class PromotionContext {
@SerializedName("experiments") val experiments: List<Experiment>? = null
@SerializedName("sid") val sessionId: String? = null
@SerializedName("pid") val visitorId: String? = null
@SerializedName("groupName") val groupName: String? = null
@SerializedName("experiments")
val campaigns: List<Campaign>? = null

@SerializedName("sid")
val sessionId: UUID? = null

@SerializedName("pid")
val visitorId: UUID? = null

@SerializedName("groupName")
val groupName: String? = null
}
Loading

0 comments on commit 5529f04

Please sign in to comment.