Skip to content

Commit 1e57a32

Browse files
authored
SegmentDestination refactor and add cdnHost config option (#34)
* refactory SegmentDestination.kt * fix failing tests * add cdn host to ConfigurationBuilder.kt * update tests
1 parent 4bdb475 commit 1e57a32

File tree

12 files changed

+63
-21
lines changed

12 files changed

+63
-21
lines changed

core/src/main/java/com/segment/analytics/kotlin/core/Analytics.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.segment.analytics.kotlin.core.platform.DestinationPlugin
44
import com.segment.analytics.kotlin.core.platform.Plugin
55
import com.segment.analytics.kotlin.core.platform.Timeline
66
import com.segment.analytics.kotlin.core.platform.plugins.ContextPlugin
7+
import com.segment.analytics.kotlin.core.platform.plugins.SegmentDestination
78
import com.segment.analytics.kotlin.core.platform.plugins.StartupQueue
89
import com.segment.analytics.kotlin.core.platform.plugins.log
910
import kotlinx.coroutines.CoroutineDispatcher

core/src/main/java/com/segment/analytics/kotlin/core/Configuration.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.segment.analytics.kotlin.core
22

3+
import com.segment.analytics.kotlin.core.Constants.DEFAULT_API_HOST
4+
import com.segment.analytics.kotlin.core.Constants.DEFAULT_CDN_HOST
35
import com.segment.analytics.kotlin.core.utilities.ConcreteStorageProvider
46
import kotlinx.coroutines.CoroutineDispatcher
57
import kotlinx.coroutines.CoroutineScope
@@ -42,7 +44,8 @@ data class Configuration(
4244
var flushInterval: Int = 30,
4345
val defaultSettings: Settings = Settings(),
4446
var autoAddSegmentDestination: Boolean = true,
45-
var apiHost: String = "api.segment.io/v1"
47+
var apiHost: String = DEFAULT_API_HOST,
48+
var cdnHost: String = DEFAULT_CDN_HOST
4649
) {
4750
fun isValid(): Boolean {
4851
return writeKey.isNotBlank() && application != null

core/src/main/java/com/segment/analytics/kotlin/core/Constants.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ package com.segment.analytics.kotlin.core
22

33
object Constants {
44
const val LIBRARY_VERSION = "1.2.0"
5+
const val DEFAULT_API_HOST = "api.segment.io/v1"
6+
const val DEFAULT_CDN_HOST = "cdn-settings.segment.com/v1"
57
}

core/src/main/java/com/segment/analytics/kotlin/core/HTTPClient.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import java.util.zip.GZIPOutputStream
1515
class HTTPClient(private val writeKey: String) {
1616
internal val authHeader = authorizationHeader(writeKey)
1717

18-
fun settings(): Connection {
18+
fun settings(cdnHost: String): Connection {
1919
val connection: HttpURLConnection =
20-
openConnection("https://cdn-settings.segment.com/v1/projects/$writeKey/settings")
20+
openConnection("https://$cdnHost/projects/$writeKey/settings")
2121
val responseCode = connection.responseCode
2222
if (responseCode != HttpURLConnection.HTTP_OK) {
2323
connection.disconnect()

core/src/main/java/com/segment/analytics/kotlin/core/Settings.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,15 @@ internal fun Analytics.update(settings: Settings, type: Plugin.UpdateType) {
5151
*/
5252
fun Analytics.checkSettings() {
5353
val writeKey = configuration.writeKey
54+
val cdnHost = configuration.cdnHost
5455

5556
// stop things; queue in case our settings have changed.
5657
store.dispatch(System.ToggleRunningAction(running = false), System::class)
5758

5859
analyticsScope.launch(ioDispatcher) {
5960
log("Fetching settings on ${Thread.currentThread().name}")
6061
val settingsObj: Settings? = try {
61-
val connection = HTTPClient(writeKey).settings()
62+
val connection = HTTPClient(writeKey).settings(cdnHost)
6263
val settingsString =
6364
connection.inputStream?.bufferedReader()?.use(BufferedReader::readText) ?: ""
6465
log("Fetched Settings: $settingsString")

core/src/main/java/com/segment/analytics/kotlin/core/compat/ConfigurationBuilder.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,7 @@ class ConfigurationBuilder (writeKey: String) {
3838

3939
fun setApiHost(apiHost: String) = apply { configuration.apiHost = apiHost}
4040

41+
fun setCdnHost(cdnHost: String) = apply { configuration.cdnHost = cdnHost}
42+
4143
fun build() = configuration
4244
}

core/src/main/java/com/segment/analytics/kotlin/core/SegmentDestination.kt renamed to core/src/main/java/com/segment/analytics/kotlin/core/platform/plugins/SegmentDestination.kt

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1-
package com.segment.analytics.kotlin.core
2-
1+
package com.segment.analytics.kotlin.core.platform.plugins
2+
3+
import com.segment.analytics.kotlin.core.AliasEvent
4+
import com.segment.analytics.kotlin.core.Analytics
5+
import com.segment.analytics.kotlin.core.BaseEvent
6+
import com.segment.analytics.kotlin.core.Constants.DEFAULT_API_HOST
7+
import com.segment.analytics.kotlin.core.GroupEvent
8+
import com.segment.analytics.kotlin.core.HTTPClient
9+
import com.segment.analytics.kotlin.core.HTTPException
10+
import com.segment.analytics.kotlin.core.IdentifyEvent
11+
import com.segment.analytics.kotlin.core.ScreenEvent
12+
import com.segment.analytics.kotlin.core.Settings
13+
import com.segment.analytics.kotlin.core.Storage
14+
import com.segment.analytics.kotlin.core.TrackEvent
15+
import com.segment.analytics.kotlin.core.emptyJsonObject
16+
import com.segment.analytics.kotlin.core.parseFilePaths
317
import com.segment.analytics.kotlin.core.platform.DestinationPlugin
418
import com.segment.analytics.kotlin.core.platform.Plugin
5-
import com.segment.analytics.kotlin.core.platform.plugins.LogType
6-
import com.segment.analytics.kotlin.core.platform.plugins.log
719
import com.segment.analytics.kotlin.core.utilities.EncodeDefaultsJson
820
import kotlinx.coroutines.launch
21+
import kotlinx.serialization.Serializable
922
import kotlinx.serialization.encodeToString
1023
import kotlinx.serialization.json.Json
1124
import kotlinx.serialization.json.encodeToJsonElement
@@ -19,6 +32,12 @@ import java.util.concurrent.ScheduledExecutorService
1932
import java.util.concurrent.TimeUnit
2033
import java.util.concurrent.atomic.AtomicInteger
2134

35+
@Serializable
36+
data class SegmentSettings(
37+
var apiKey: String,
38+
var apiHost: String = DEFAULT_API_HOST,
39+
)
40+
2241
/**
2342
* Segment Analytics plugin that is used to send events to Segment's tracking api, in the choice of region.
2443
* How it works
@@ -30,7 +49,7 @@ class SegmentDestination(
3049
private var apiKey: String,
3150
private val flushCount: Int = 20,
3251
private val flushIntervalInMillis: Long = 30 * 1000, // 30s
33-
private var apiHost: String = "api.segment.io/v1"
52+
private var apiHost: String = DEFAULT_API_HOST
3453
) : DestinationPlugin() {
3554

3655
override val key: String = "Segment.io"
@@ -66,10 +85,11 @@ class SegmentDestination(
6685

6786
private inline fun <reified T : BaseEvent> enqueue(payload: T) {
6887
// needs to be inline reified for encoding using Json
69-
val jsonVal = EncodeDefaultsJson.encodeToJsonElement(payload).jsonObject.filterNot { (k, v) ->
70-
// filter out empty userId and traits values
71-
(k == "userId" && v.jsonPrimitive.content.isBlank()) || (k == "traits" && v == emptyJsonObject)
72-
}
88+
val jsonVal = EncodeDefaultsJson.encodeToJsonElement(payload)
89+
.jsonObject.filterNot { (k, v) ->
90+
// filter out empty userId and traits values
91+
(k == "userId" && v.jsonPrimitive.content.isBlank()) || (k == "traits" && v == emptyJsonObject)
92+
}
7393

7494
val stringVal = Json.encodeToString(jsonVal)
7595
analytics.log("$key running $stringVal")
@@ -109,9 +129,11 @@ class SegmentDestination(
109129
}
110130

111131
override fun update(settings: Settings, type: Plugin.UpdateType) {
112-
settings.integrations[key]?.jsonObject?.let {
113-
apiKey = it["apiKey"]?.jsonPrimitive?.content ?: apiKey
114-
apiHost = it["apiHost"]?.jsonPrimitive?.content ?: apiHost
132+
if (settings.isDestinationEnabled(key)) {
133+
settings.destinationSettings<SegmentSettings>(key)?.let {
134+
apiKey = it.apiKey
135+
apiHost = it.apiHost
136+
}
115137
}
116138
}
117139

core/src/test/kotlin/com/segment/analytics/kotlin/core/HTTPClientTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class HTTPClientTests {
2222

2323
@Test
2424
fun `upload connection has correct configuration`() {
25-
httpClient.settings().connection.let {
25+
httpClient.settings("cdn-settings.segment.com/v1").connection.let {
2626
assertEquals(
2727
"https://cdn-settings.segment.com/v1/projects/1vNgUqwJeCHmqgI9S1sOm9UHCyfYqbaQ/settings",
2828
it.url.toString()

core/src/test/kotlin/com/segment/analytics/kotlin/core/SegmentDestinationTests.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.segment.analytics.kotlin.core
22

33
import com.segment.analytics.kotlin.core.platform.plugins.LogType
44
import com.segment.analytics.kotlin.core.platform.plugins.Logger
5+
import com.segment.analytics.kotlin.core.platform.plugins.SegmentDestination
56
import com.segment.analytics.kotlin.core.utilities.ConcreteStorageProvider
67
import com.segment.analytics.kotlin.core.utilities.EncodeDefaultsJson
78
import com.segment.analytics.kotlin.core.utilities.StorageImpl

core/src/test/kotlin/com/segment/analytics/kotlin/core/SettingsTests.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class SettingsTests {
3434
)
3535
val httpConnection: HttpURLConnection = mockk()
3636
val connection = object : Connection(httpConnection, settingsStream, null) {}
37-
every { anyConstructed<HTTPClient>().settings() } returns connection
37+
every { anyConstructed<HTTPClient>().settings("cdn-settings.segment.com/v1") } returns connection
3838
}
3939

4040
@BeforeEach
@@ -55,7 +55,7 @@ class SettingsTests {
5555
fun `checkSettings updates settings`() = runBlocking {
5656
val system = analytics.store.currentState(System::class)
5757
val curSettings = system?.settings
58-
Assertions.assertEquals(
58+
assertEquals(
5959
Settings(
6060
integrations = buildJsonObject {
6161
put(

0 commit comments

Comments
 (0)