Skip to content

Commit

Permalink
feat: add ingestion_metadata field (#63)
Browse files Browse the repository at this point in the history
* feat: add ingestion_metadata field

* feat: clone object from configure when setting event
  • Loading branch information
liuyang1520 authored Sep 8, 2022
1 parent f7b50d1 commit 354ec7b
Show file tree
Hide file tree
Showing 14 changed files with 159 additions and 11 deletions.
4 changes: 3 additions & 1 deletion android/src/main/java/com/amplitude/android/Configuration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.amplitude.core.EventCallBack
import com.amplitude.core.LoggerProvider
import com.amplitude.core.ServerZone
import com.amplitude.core.StorageProvider
import com.amplitude.core.events.IngestionMetadata
import com.amplitude.core.events.Plan

open class Configuration @JvmOverloads constructor(
Expand All @@ -27,6 +28,7 @@ open class Configuration @JvmOverloads constructor(
override var serverZone: ServerZone = ServerZone.US,
override var serverUrl: String? = null,
override var plan: Plan? = null,
override var ingestionMetadata: IngestionMetadata? = null,
val useAdvertisingIdForDeviceId: Boolean = false,
val useAppSetIdForDeviceId: Boolean = false,
val newDeviceIdPerInstall: Boolean = false,
Expand All @@ -36,7 +38,7 @@ open class Configuration @JvmOverloads constructor(
val flushEventsOnClose: Boolean = true,
val minTimeBetweenSessionsMillis: Long = MIN_TIME_BETWEEN_SESSIONS_MILLIS,
val trackingSessionEvents: Boolean = true
) : Configuration(apiKey, flushQueueSize, flushIntervalMillis, instanceName, optOut, storageProvider, loggerProvider, minIdLength, partnerId, callback, flushMaxRetries, useBatch, serverZone, serverUrl, plan) {
) : Configuration(apiKey, flushQueueSize, flushIntervalMillis, instanceName, optOut, storageProvider, loggerProvider, minIdLength, partnerId, callback, flushMaxRetries, useBatch, serverZone, serverUrl, plan, ingestionMetadata) {
companion object {
const val MIN_TIME_BETWEEN_SESSIONS_MILLIS: Long = 300000
}
Expand Down
5 changes: 5 additions & 0 deletions android/src/main/java/com/amplitude/android/events/Export.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.amplitude.core.events.EventOptions
import com.amplitude.core.events.GroupIdentifyEvent
import com.amplitude.core.events.Identify
import com.amplitude.core.events.IdentifyEvent
import com.amplitude.core.events.IngestionMetadata
import com.amplitude.core.events.Plan
import com.amplitude.core.events.Revenue
import com.amplitude.core.events.RevenueEvent
Expand All @@ -22,3 +23,7 @@ open class Plan @JvmOverloads constructor(
version: String? = null,
versionId: String? = null
) : Plan(branch, source, version, versionId)
open class IngestionMetadata @JvmOverloads constructor(
sourceName: String? = null,
sourceVersion: String? = null,
) : IngestionMetadata(sourceName, sourceVersion)
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ class AndroidContextPlugin : Plugin {
}
event.plan ?: let {
amplitude.configuration.plan ?. let {
event.plan = it
event.plan = it.clone()
}
}
event.ingestionMetadata ?: let {
amplitude.configuration.ingestionMetadata ?. let {
event.ingestionMetadata = it.clone()
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/com/amplitude/core/Configuration.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.amplitude.core

import com.amplitude.core.events.BaseEvent
import com.amplitude.core.events.IngestionMetadata
import com.amplitude.core.events.Plan
import com.amplitude.core.utilities.ConsoleLoggerProvider
import com.amplitude.core.utilities.InMemoryStorageProvider
Expand All @@ -22,7 +23,8 @@ open class Configuration @JvmOverloads constructor(
open var useBatch: Boolean = false,
open var serverZone: ServerZone = ServerZone.US,
open var serverUrl: String? = null,
open var plan: Plan? = null
open var plan: Plan? = null,
open var ingestionMetadata: IngestionMetadata? = null
) {

companion object {
Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/com/amplitude/core/events/BaseEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ open class BaseEvent : EventOptions() {
library ?: let { library = options.library }
ip ?: let { ip = options.ip }
plan ?: let { plan = options.plan }
ingestionMetadata ?: let { ingestionMetadata = options.ingestionMetadata }
revenue ?: let { revenue = options.revenue }
price ?: let { price = options.price }
quantity ?: let { quantity = options.quantity }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ open class EventOptions {
var library: String? = null
var ip: String? = null
var plan: Plan? = null
var ingestionMetadata: IngestionMetadata? = null
var revenue: Double? = null
var price: Double? = null
var quantity: Int? = null
Expand Down
48 changes: 48 additions & 0 deletions core/src/main/java/com/amplitude/core/events/IngestionMetadata.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.amplitude.core.events

import com.amplitude.common.jvm.ConsoleLogger
import org.json.JSONException
import org.json.JSONObject

open class IngestionMetadata @JvmOverloads constructor(
val sourceName: String? = null,
val sourceVersion: String? = null,
) {

/**
* Get JSONObject of current ingestion metadata
* @return JSONObject including ingestion metadata information
*/
internal fun toJSONObject(): JSONObject {
val jsonObject = JSONObject()
try {
if (!sourceName.isNullOrEmpty()) {
jsonObject.put(AMP_INGESTION_METADATA_SOURCE_NAME, sourceName)
}
if (!sourceVersion.isNullOrEmpty()) {
jsonObject.put(AMP_INGESTION_METADATA_SOURCE_VERSION, sourceVersion)
}
} catch (e: JSONException) {
ConsoleLogger.logger.error("JSON Serialization of ingestion metadata object failed")
}
return jsonObject
}

/**
* Get a cloned IngestionMetadata object, to isolate the potentially value changes
*/
fun clone(): IngestionMetadata {
return IngestionMetadata(sourceName, sourceVersion)
}

companion object {
const val AMP_INGESTION_METADATA_SOURCE_NAME = "source_name"
const val AMP_INGESTION_METADATA_SOURCE_VERSION = "source_version"

internal fun fromJSONObject(jsonObject: JSONObject): IngestionMetadata {
val branch = jsonObject.optString(AMP_INGESTION_METADATA_SOURCE_NAME, null)
val source = jsonObject.optString(AMP_INGESTION_METADATA_SOURCE_VERSION, null)
return IngestionMetadata(branch, source)
}
}
}
11 changes: 9 additions & 2 deletions core/src/main/java/com/amplitude/core/events/Plan.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ open class Plan @JvmOverloads constructor(
) {

/**
* Get JSONObject of current tacking plan
* Get JSONObject of current tracking plan
* @return JSONObject including plan information
*/
internal fun toJSONObject(): JSONObject? {
internal fun toJSONObject(): JSONObject {
val plan = JSONObject()
try {
if (!branch.isNullOrEmpty()) {
Expand All @@ -36,6 +36,13 @@ open class Plan @JvmOverloads constructor(
return plan
}

/**
* Get a cloned Plan object, to isolate the potentially value changes
*/
fun clone(): Plan {
return Plan(branch, source, version, versionId)
}

companion object {
const val AMP_PLAN_BRANCH = "branch"
const val AMP_PLAN_SOURCE = "source"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ class ContextPlugin : Plugin {
}
event.plan ?: let {
amplitude.configuration.plan ?. let {
event.plan = it
event.plan = it.clone()
}
}
event.ingestionMetadata ?: let {
amplitude.configuration.ingestionMetadata ?. let {
event.ingestionMetadata = it.clone()
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/java/com/amplitude/core/utilities/JSONUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.amplitude.core.utilities

import com.amplitude.core.Constants
import com.amplitude.core.events.BaseEvent
import com.amplitude.core.events.IngestionMetadata
import com.amplitude.core.events.Plan
import org.json.JSONArray
import org.json.JSONException
Expand Down Expand Up @@ -54,6 +55,9 @@ object JSONUtil {
event.plan?. let {
eventJSON.put("plan", it.toJSONObject())
}
event.ingestionMetadata?. let {
eventJSON.put("ingestion_metadata", it.toJSONObject())
}
return eventJSON
}

Expand Down Expand Up @@ -199,6 +203,7 @@ internal fun JSONObject.toBaseEvent(): BaseEvent {
event.library = if (this.has("library")) this.getString("library") else null
event.partnerId = this.optionalString("partner_id", null)
event.plan = if (this.has("plan")) Plan.fromJSONObject(this.getJSONObject("plan")) else null
event.ingestionMetadata = if (this.has("ingestion_metadata")) IngestionMetadata.fromJSONObject(this.getJSONObject("ingestion_metadata")) else null
return event
}

Expand Down
6 changes: 5 additions & 1 deletion core/src/test/kotlin/com/amplitude/core/AmplitudeTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.amplitude.core.events.GroupIdentifyEvent
import com.amplitude.core.events.Identify
import com.amplitude.core.events.IdentifyEvent
import com.amplitude.core.events.IdentifyOperation
import com.amplitude.core.events.IngestionMetadata
import com.amplitude.core.events.Plan
import com.amplitude.core.events.Revenue
import com.amplitude.core.events.RevenueEvent
Expand Down Expand Up @@ -39,7 +40,8 @@ internal class AmplitudeTest {
mockHTTPClient(createSuccessResponse())
val testApiKey = "test-123"
val plan = Plan("test-branch", "test")
amplitude = testAmplitude(Configuration(testApiKey, plan = plan))
val ingestionMetadata = IngestionMetadata("ampli", "2.0.0")
amplitude = testAmplitude(Configuration(testApiKey, plan = plan, ingestionMetadata = ingestionMetadata))
}

@Nested
Expand All @@ -63,6 +65,7 @@ internal class AmplitudeTest {
assertEquals(mapOf(Pair("foo", "bar")), it.eventProperties)
assertEquals("CA", it.region)
assertEquals("test", it.plan?.source)
assertEquals("ampli", it.ingestionMetadata?.sourceName)
}
}

Expand All @@ -87,6 +90,7 @@ internal class AmplitudeTest {
assertEquals("CA", it.region)
assertEquals("SF", it.city)
assertEquals("test", it.plan?.source)
assertEquals("ampli", it.ingestionMetadata?.sourceName)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ class BaseEventTest {
event.country = "US"
val eventOptions = EventOptions()
val plan = Plan(branch = "test")
val ingestionMetadata = IngestionMetadata(sourceName = "ampli")
eventOptions.userId = "user_id"
eventOptions.country = "DE"
eventOptions.plan = plan
eventOptions.ingestionMetadata = ingestionMetadata
event.mergeEventOptions(eventOptions)
assertEquals(event.userId, "user_id")
assertEquals(event.country, "US")
assertEquals(event.plan, plan)
assertEquals(event.ingestionMetadata, ingestionMetadata)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.amplitude.core.events

import org.json.JSONObject
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class IngestionMetadataTest {

@Test
fun `test ingestionMetadata to json object`() {
val sourceName = "ampli"
val sourceVersion = "2.0.0"
val ingestionMetadata = IngestionMetadata(sourceName, sourceVersion)
val result = ingestionMetadata.toJSONObject()
assertEquals(sourceName, result.getString(IngestionMetadata.AMP_INGESTION_METADATA_SOURCE_NAME))
assertEquals(sourceVersion, result.getString(IngestionMetadata.AMP_INGESTION_METADATA_SOURCE_VERSION))
}

@Test
fun `test ingestionMetadata clone new object`() {
val sourceName = "ampli"
val sourceVersion = "2.0.0"
val ingestionMetadata = IngestionMetadata(sourceName, sourceVersion)
val clone = ingestionMetadata.clone()
assertEquals(sourceName, clone.sourceName)
assertEquals(sourceVersion, clone.sourceVersion)
assertFalse(ingestionMetadata === clone)
}

@Test
fun `test ingestionMetadata from json object`() {
val jsonObject = JSONObject()
val sourceName = "ampli"
val sourceVersion = "2.0.0"
jsonObject.put(IngestionMetadata.AMP_INGESTION_METADATA_SOURCE_NAME, sourceName)
.put(IngestionMetadata.AMP_INGESTION_METADATA_SOURCE_VERSION, sourceVersion)
val ingestionMetadata = IngestionMetadata.fromJSONObject(jsonObject)
assertEquals(sourceName, ingestionMetadata.sourceName)
assertEquals(sourceVersion, ingestionMetadata.sourceVersion)
}
}
24 changes: 20 additions & 4 deletions core/src/test/kotlin/com/amplitude/core/events/PlanTest.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.amplitude.core.events

import org.json.JSONObject
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
Expand All @@ -16,10 +17,25 @@ class PlanTest {
val versionId = "9ec23ba0-275f-468f-80d1-66b88bff9529"
val plan = Plan(branch, source, version, versionId)
val result = plan.toJSONObject()
assertEquals(branch, result?.getString(Plan.AMP_PLAN_BRANCH))
assertEquals(source, result?.getString(Plan.AMP_PLAN_SOURCE))
assertEquals(version, result?.getString(Plan.AMP_PLAN_VERSION))
assertEquals(versionId, result?.getString(Plan.AMP_PLAN_VERSION_ID))
assertEquals(branch, result.getString(Plan.AMP_PLAN_BRANCH))
assertEquals(source, result.getString(Plan.AMP_PLAN_SOURCE))
assertEquals(version, result.getString(Plan.AMP_PLAN_VERSION))
assertEquals(versionId, result.getString(Plan.AMP_PLAN_VERSION_ID))
}

@Test
fun `test Plan clone new object`() {
val branch = "main"
val version = "1.0.0"
val source = "mobile"
val versionId = "9ec23ba0-275f-468f-80d1-66b88bff9529"
val plan = Plan(branch, source, version, versionId)
val clone = plan.clone()
assertEquals(branch, plan.branch)
assertEquals(source, plan.source)
assertEquals(version, plan.version)
assertEquals(versionId, plan.versionId)
Assertions.assertFalse(plan === clone)
}

@Test
Expand Down

0 comments on commit 354ec7b

Please sign in to comment.