All Downloads are FREE. Search and download functionalities are using the official Maven repository.

.evaluation-proxy-core.0.6.0.source-code.Config.kt Maven / Gradle / Ivy

The newest version!
package com.amplitude

import com.amplitude.util.booleanEnv
import com.amplitude.util.intEnv
import com.amplitude.util.json
import com.amplitude.util.longEnv
import com.amplitude.util.stringEnv
import com.amplitude.util.yaml
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import java.io.File

@Serializable
data class ProjectsFile(
    val projects: List,
) {
    companion object {
        fun fromEnv(): ProjectsFile {
            val project = ProjectConfiguration.fromEnv()
            return ProjectsFile(listOf(project))
        }

        fun fromFile(path: String): ProjectsFile {
            val data = File(path).readText()
            return if (path.endsWith(".yaml") || path.endsWith(".yml")) {
                yaml.decodeFromString(data)
            } else if (path.endsWith(".json")) {
                json.decodeFromString(data)
            } else {
                throw IllegalArgumentException("Proxy configuration file format must be \".yaml\" or \".yml\". Found $path")
            }
        }
    }
}

@Serializable
data class ConfigurationFile(
    val configuration: Configuration = Configuration(),
) {
    companion object {
        fun fromEnv(): ConfigurationFile {
            val configuration = Configuration.fromEnv()
            return ConfigurationFile(configuration)
        }

        fun fromFile(path: String): ConfigurationFile {
            val data = File(path).readText()
            return if (path.endsWith(".yaml") || path.endsWith(".yml")) {
                yaml.decodeFromString(data)
            } else if (path.endsWith(".json")) {
                json.decodeFromString(data)
            } else {
                throw IllegalArgumentException("Proxy configuration file format must be \".yaml\", \".yml\", or \".json\". Found $path")
            }
        }
    }
}

@Serializable
data class ProjectConfiguration(
    val apiKey: String,
    val secretKey: String,
    val managementKey: String,
) {
    companion object {
        fun fromEnv(): ProjectConfiguration {
            val apiKey = checkNotNull(stringEnv(EnvKey.API_KEY)) { "${EnvKey.API_KEY} environment variable must be set." }
            val secretKey = checkNotNull(stringEnv(EnvKey.SECRET_KEY)) { "${EnvKey.SECRET_KEY} environment variable must be set." }
            val managementKey =
                checkNotNull(
                    stringEnv(EnvKey.EXPERIMENT_MANAGEMENT_KEY),
                ) { "${EnvKey.EXPERIMENT_MANAGEMENT_KEY} environment variable must be set." }
            return ProjectConfiguration(apiKey, secretKey, managementKey)
        }
    }
}

@Serializable
data class Configuration(
    val port: Int = Default.PORT,
    val serverZone: String = Default.SERVER_ZONE,
    val serverUrl: String = getServerUrl(serverZone),
    val cohortServerUrl: String = getCohortServerUrl(serverZone),
    val managementServerUrl: String = getManagementServerUrl(serverZone),
    val analyticsServerUrl: String = getAnalyticsServerUrl(serverZone),
    val deploymentSyncIntervalMillis: Long = Default.DEPLOYMENT_SYNC_INTERVAL_MILLIS,
    val flagSyncIntervalMillis: Long = Default.FLAG_SYNC_INTERVAL_MILLIS,
    val cohortSyncIntervalMillis: Long = Default.COHORT_SYNC_INTERVAL_MILLIS,
    val maxCohortSize: Int = Default.MAX_COHORT_SIZE,
    val assignment: AssignmentConfiguration = AssignmentConfiguration(),
    val redis: RedisConfiguration? = null,
) {
    companion object {
        fun fromEnv() =
            Configuration(
                port = intEnv(EnvKey.PORT, Default.PORT)!!,
                serverZone = stringEnv(EnvKey.SERVER_ZONE, Default.SERVER_ZONE)!!,
                serverUrl = stringEnv(EnvKey.SERVER_URL, Default.US_SERVER_URL)!!,
                cohortServerUrl = stringEnv(EnvKey.COHORT_SERVER_URL, Default.US_COHORT_SERVER_URL)!!,
                managementServerUrl = stringEnv(EnvKey.MANAGEMENT_SERVER_URL, Default.US_MANAGEMENT_SERVER_URL)!!,
                analyticsServerUrl = stringEnv(EnvKey.ANALYTICS_SERVER_URL, Default.US_ANALYTICS_SERVER_URL)!!,
                deploymentSyncIntervalMillis =
                    longEnv(
                        EnvKey.DEPLOYMENT_SYNC_INTERVAL_MILLIS,
                        Default.DEPLOYMENT_SYNC_INTERVAL_MILLIS,
                    )!!,
                flagSyncIntervalMillis =
                    longEnv(
                        EnvKey.FLAG_SYNC_INTERVAL_MILLIS,
                        Default.FLAG_SYNC_INTERVAL_MILLIS,
                    )!!,
                cohortSyncIntervalMillis =
                    longEnv(
                        EnvKey.COHORT_SYNC_INTERVAL_MILLIS,
                        Default.COHORT_SYNC_INTERVAL_MILLIS,
                    )!!,
                maxCohortSize = intEnv(EnvKey.MAX_COHORT_SIZE, Default.MAX_COHORT_SIZE)!!,
                assignment = AssignmentConfiguration.fromEnv(),
                redis = RedisConfiguration.fromEnv(),
            )
    }
}

@Serializable
data class AssignmentConfiguration(
    val filterCapacity: Int = Default.ASSIGNMENT_FILTER_CAPACITY,
    val eventUploadThreshold: Int = Default.ASSIGNMENT_EVENT_UPLOAD_THRESHOLD,
    val eventUploadPeriodMillis: Int = Default.ASSIGNMENT_EVENT_UPLOAD_PERIOD_MILLIS,
    val useBatchMode: Boolean = Default.ASSIGNMENT_USE_BATCH_MODE,
) {
    companion object {
        fun fromEnv() =
            AssignmentConfiguration(
                filterCapacity =
                    intEnv(
                        EnvKey.ASSIGNMENT_FILTER_CAPACITY,
                        Default.ASSIGNMENT_FILTER_CAPACITY,
                    )!!,
                eventUploadThreshold =
                    intEnv(
                        EnvKey.ASSIGNMENT_EVENT_UPLOAD_THRESHOLD,
                        Default.ASSIGNMENT_EVENT_UPLOAD_THRESHOLD,
                    )!!,
                eventUploadPeriodMillis =
                    intEnv(
                        EnvKey.ASSIGNMENT_EVENT_UPLOAD_PERIOD_MILLIS,
                        Default.ASSIGNMENT_EVENT_UPLOAD_PERIOD_MILLIS,
                    )!!,
                useBatchMode =
                    booleanEnv(
                        EnvKey.ASSIGNMENT_USE_BATCH_MODE,
                        Default.ASSIGNMENT_USE_BATCH_MODE,
                    ),
            )
    }
}

@Serializable
data class RedisConfiguration(
    val uri: String? = null,
    val readOnlyUri: String? = uri,
    val prefix: String = Default.REDIS_PREFIX,
    val scanLimit: Long = Default.REDIS_SCAN_LIMIT,
) {
    companion object {
        fun fromEnv(): RedisConfiguration? {
            val redisUri = stringEnv(EnvKey.REDIS_URI, Default.REDIS_URI)
            return if (redisUri != null) {
                val redisReadOnlyUri = stringEnv(EnvKey.REDIS_READ_ONLY_URI, Default.REDIS_READ_ONLY_URI) ?: redisUri
                val redisPrefix = stringEnv(EnvKey.REDIS_PREFIX, Default.REDIS_PREFIX)!!
                val redisScanLimit = longEnv(EnvKey.REDIS_SCAN_LIMIT, Default.REDIS_SCAN_LIMIT)!!
                RedisConfiguration(
                    uri = redisUri,
                    readOnlyUri = redisReadOnlyUri,
                    prefix = redisPrefix,
                    scanLimit = redisScanLimit,
                )
            } else {
                null
            }
        }
    }
}

object EnvKey {
    const val PORT = "AMPLITUDE_PORT"
    const val SERVER_ZONE = "AMPLITUDE_SERVER_ZONE"
    const val SERVER_URL = "AMPLITUDE_SERVER_URL"
    const val COHORT_SERVER_URL = "AMPLITUDE_COHORT_SERVER_URL"
    const val MANAGEMENT_SERVER_URL = "AMPLITUDE_MANAGEMENT_SERVER_URL"
    const val ANALYTICS_SERVER_URL = "AMPLITUDE_ANALYTICS_SERVER_URL"

    const val API_KEY = "AMPLITUDE_API_KEY"
    const val SECRET_KEY = "AMPLITUDE_SECRET_KEY"
    const val EXPERIMENT_MANAGEMENT_KEY = "AMPLITUDE_EXPERIMENT_MANAGEMENT_API_KEY"

    const val DEPLOYMENT_SYNC_INTERVAL_MILLIS = "AMPLITUDE_DEPLOYMENT_SYNC_INTERVAL_MILLIS"
    const val FLAG_SYNC_INTERVAL_MILLIS = "AMPLITUDE_FLAG_SYNC_INTERVAL_MILLIS"
    const val COHORT_SYNC_INTERVAL_MILLIS = "AMPLITUDE_COHORT_SYNC_INTERVAL_MILLIS"
    const val MAX_COHORT_SIZE = "AMPLITUDE_MAX_COHORT_SIZE"

    const val ASSIGNMENT_FILTER_CAPACITY = "AMPLITUDE_ASSIGNMENT_FILTER_CAPACITY"
    const val ASSIGNMENT_EVENT_UPLOAD_THRESHOLD = "AMPLITUDE_ASSIGNMENT_EVENT_UPLOAD_THRESHOLD"
    const val ASSIGNMENT_EVENT_UPLOAD_PERIOD_MILLIS = "AMPLITUDE_ASSIGNMENT_EVENT_UPLOAD_PERIOD_MILLIS"
    const val ASSIGNMENT_USE_BATCH_MODE = "AMPLITUDE_ASSIGNMENT_USE_BATCH_MODE"

    const val REDIS_URI = "AMPLITUDE_REDIS_URI"
    const val REDIS_READ_ONLY_URI = "AMPLITUDE_REDIS_READ_ONLY_URI"
    const val REDIS_PREFIX = "AMPLITUDE_REDIS_PREFIX"
    const val REDIS_SCAN_LIMIT = "AMPLITUDE_REDIS_SCAN_LIMIT"
}

object Default {
    const val PORT = 3546
    const val SERVER_ZONE = "US"
    const val US_SERVER_URL = "https://flag.lab.amplitude.com"
    const val US_COHORT_SERVER_URL = "https://cohort-v2.lab.amplitude.com"
    const val US_MANAGEMENT_SERVER_URL = "https://experiment.amplitude.com"
    const val US_ANALYTICS_SERVER_URL = "https://api2.amplitude.com/2/httpapi"
    const val EU_SERVER_URL = "https://flag.lab.eu.amplitude.com"
    const val EU_COHORT_SERVER_URL = "https://cohort-v2.lab.eu.amplitude.com"
    const val EU_MANAGEMENT_SERVER_URL = "https://experiment.eu.amplitude.com"
    const val EU_ANALYTICS_SERVER_URL = "https://api.eu.amplitude.com/2/httpapi"
    const val DEPLOYMENT_SYNC_INTERVAL_MILLIS = 60 * 1000L
    const val FLAG_SYNC_INTERVAL_MILLIS = 10 * 1000L
    const val COHORT_SYNC_INTERVAL_MILLIS = 60 * 1000L
    const val MAX_COHORT_SIZE = Int.MAX_VALUE

    const val ASSIGNMENT_FILTER_CAPACITY = 1 shl 20
    const val ASSIGNMENT_EVENT_UPLOAD_THRESHOLD = 100
    const val ASSIGNMENT_EVENT_UPLOAD_PERIOD_MILLIS = 10000
    const val ASSIGNMENT_USE_BATCH_MODE = true

    val REDIS_URI: String? = null
    val REDIS_READ_ONLY_URI: String? = null
    const val REDIS_PREFIX = "amplitude"
    const val REDIS_SCAN_LIMIT = 10000L
}

private fun getServerUrl(zone: String): String {
    return if (zone == "EU") {
        Default.EU_SERVER_URL
    } else {
        Default.US_SERVER_URL
    }
}

private fun getCohortServerUrl(zone: String): String {
    return if (zone == "EU") {
        Default.EU_COHORT_SERVER_URL
    } else {
        Default.US_COHORT_SERVER_URL
    }
}

private fun getManagementServerUrl(zone: String): String {
    return if (zone == "EU") {
        Default.EU_MANAGEMENT_SERVER_URL
    } else {
        Default.US_MANAGEMENT_SERVER_URL
    }
}

private fun getAnalyticsServerUrl(zone: String): String {
    return if (zone == "EU") {
        Default.EU_ANALYTICS_SERVER_URL
    } else {
        Default.US_ANALYTICS_SERVER_URL
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy