From a03625dde353ce5360f99e9bfc8bf9c16d622583 Mon Sep 17 00:00:00 2001 From: Elizabeth Worstell Date: Thu, 19 Oct 2023 15:00:43 -0700 Subject: [PATCH] add ad-kotlin module in online-boutique --- .../services/ad-kotlin/pom.xml | 177 ++++++++++++++++++ .../ad-kotlin/src/main/kotlin/ftl/ad/Ad.kt | 78 ++++++++ 2 files changed, 255 insertions(+) create mode 100644 examples/online-boutique/services/ad-kotlin/pom.xml create mode 100644 examples/online-boutique/services/ad-kotlin/src/main/kotlin/ftl/ad/Ad.kt diff --git a/examples/online-boutique/services/ad-kotlin/pom.xml b/examples/online-boutique/services/ad-kotlin/pom.xml new file mode 100644 index 0000000000..ba71348f13 --- /dev/null +++ b/examples/online-boutique/services/ad-kotlin/pom.xml @@ -0,0 +1,177 @@ + + + 4.0.0 + xyz.block + ad-kotlin + 1.0-SNAPSHOT + + + 1.0-SNAPSHOT + 11 + 1.9.0 + true + + + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + ${project.groupId} + ftl-runtime + ${ftl.version} + + + ${project.groupId} + ftl-generator + ${ftl.version} + + + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + compile + + compile + + + + ${project.basedir}/src/main/kotlin + + + + + test-compile + + test-compile + + + + ${project.basedir}/src/test/kotlin + + + + + + + ksp + + + + + + + + com.dyescape + kotlin-maven-symbol-processing + 1.6 + + + ${project.groupId} + ftl-runtime + ${ftl.version} + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.2.0 + + + initialize + + copy + + + + + xyz.block + ftl-generator + ${ftl.version} + jar-with-dependencies + ftl-generator.jar + + + + + + copy-dependencies + compile + + copy-dependencies + + + ${project.build.directory}/dependency + runtime + + + + build-classpath + compile + + build-classpath + + + ${project.build.directory}/classpath.txt + dependency + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + + initialize + + exec + + + java + + -jar + target/dependency/ftl-generator.jar + --endpoint=http://127.0.0.1:8892 + --dest=${project.build.directory} + --module=ad + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.2.0 + + + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/ftl + + + + + + + + \ No newline at end of file diff --git a/examples/online-boutique/services/ad-kotlin/src/main/kotlin/ftl/ad/Ad.kt b/examples/online-boutique/services/ad-kotlin/src/main/kotlin/ftl/ad/Ad.kt new file mode 100644 index 0000000000..ea57769fc0 --- /dev/null +++ b/examples/online-boutique/services/ad-kotlin/src/main/kotlin/ftl/ad/Ad.kt @@ -0,0 +1,78 @@ +package ftl.ad + +import com.google.gson.Gson +import com.google.gson.annotations.SerializedName +import com.google.gson.reflect.TypeToken +import xyz.block.ftl.Context +import xyz.block.ftl.Ingress +import xyz.block.ftl.Method +import xyz.block.ftl.Verb +import xyz.block.ftl.serializer.makeGson +import java.util.* + +data class Ad(@SerializedName("RedirectURL") val redirectUrl: String, @SerializedName("Text") val text: String) +data class AdRequest(val contextKeys: List) +data class AdResponse(val ads: List) + +class AdModule { + private val database: Map = loadDatabase() + + @Throws(Exception::class) + @Verb + @Ingress(Method.GET, "/get") + fun get(context: Context, req: AdRequest): AdResponse { + return when { + req.contextKeys.isNotEmpty() -> AdResponse(ads = contextualAds(req.contextKeys)) + else -> AdResponse(ads = randomAds()) + } + } + + private fun contextualAds(contextKeys: List): List { + return contextKeys.map { database[it] ?: throw Exception("no ad registered for this context key") } + } + + private fun randomAds(): List { + val ads = mutableListOf() + val random = Random() + repeat(MAX_ADS_TO_SERVE) { + ads.add(database.entries.elementAt(random.nextInt(database.size)).value) + } + return ads + } + + companion object { + private const val MAX_ADS_TO_SERVE = 2 + private const val DATABASE_JSON = "{\n" + + " \"hair\": {\n" + + " \"RedirectURL\": \"/product/2ZYFJ3GM2N\",\n" + + " \"Text\": \"Hairdryer for sale. 50% off.\"\n" + + " },\n" + + " \"clothing\": {\n" + + " \"RedirectURL\": \"/product/66VCHSJNUP\",\n" + + " \"Text\": \"Tank top for sale. 20% off.\"\n" + + " },\n" + + " \"accessories\": {\n" + + " \"RedirectURL\": \"/product/1YMWWN1N4O\",\n" + + " \"Text\": \"Watch for sale. Buy one, get second kit for free\"\n" + + " },\n" + + " \"footwear\": {\n" + + " \"RedirectURL\": \"/product/L9ECAV7KIM\",\n" + + " \"Text\": \"Loafers for sale. Buy one, get second one for free\"\n" + + " },\n" + + " \"decor\": {\n" + + " \"RedirectURL\": \"/product/0PUK6V6EV0\",\n" + + " \"Text\": \"Candle holder for sale. 30% off.\"\n" + + " },\n" + + " \"kitchen\": {\n" + + " \"RedirectURL\": \"/product/9SIQT8TOJO\",\n" + + " \"Text\": \"Bamboo glass jar for sale. 10% off.\"\n" + + " }\n" + + "}" + + private fun loadDatabase(): Map { + return makeGson().fromJson>(DATABASE_JSON) + } + + inline fun Gson.fromJson(json: String) = fromJson(json, object : TypeToken() {}.type) + } +}