From 1a22043cf22c2ec0b03b8664efe21177e762f291 Mon Sep 17 00:00:00 2001 From: "gowthaman.b" Date: Sat, 11 Nov 2023 18:14:57 +0530 Subject: [PATCH] wireup script execution --- .idea/kotlinc.xml | 2 +- api.http | 4 ++-- app-sample.properties | 2 +- build.gradle.kts | 7 ++++--- .../com/restapi/controllers/Entities.kt | 12 +++++++++-- .../kotlin/com/restapi/integ/Scripting.kt | 20 +++++++++++++++---- .../dbmigration/1.0.1__initial_data.sql | 6 ++++-- src/main/resources/scripts/vehicle.kts | 17 ++++++++++++++++ 8 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/scripts/vehicle.kts diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index fdf8d99..e805548 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/api.http b/api.http index 9b38958..84b8379 100644 --- a/api.http +++ b/api.http @@ -5,9 +5,9 @@ Authorization: {{auth-token}} { "data": { - "number": "KA01MU0556" + "number": "TN36AS1206" }, - "uniqueIdentifier": "KA01MU0556" + "uniqueIdentifier": "TN36AS1206" } ### create row, with autogenerated identifier diff --git a/app-sample.properties b/app-sample.properties index 48a2cd1..7ed0130 100644 --- a/app-sample.properties +++ b/app-sample.properties @@ -11,4 +11,4 @@ app.iam.realm=forewarn-dev app.iam.client=forewarn app.iam.client_redirect_uri=http://localhost:9001/auth/code app.cache.redis_uri=redis://127.0.0.1:6379/0 -app.scripts.path=/tmp \ No newline at end of file +app.scripts.path=/Users/gowthaman.b/IdeaProjects/rmc_modules_api/src/main/resources/scripts \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 03dfed3..78d7499 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - kotlin("jvm") version "1.9.0" - kotlin("kapt") version "1.9.0" + kotlin("jvm") version "1.9.20" + kotlin("kapt") version "1.9.20" id("idea") id("io.ebean") version "13.23.2" application @@ -29,7 +29,8 @@ dependencies { implementation("ch.qos.logback:logback-classic:1.4.11") implementation("org.bitbucket.b_c:jose4j:0.9.3") implementation("redis.clients:jedis:5.0.2") - implementation("org.jetbrains.kotlin:kotlin-scripting-jsr223:1.9.0") + implementation("org.jetbrains.kotlin:kotlin-scripting-jsr223:1.9.20") + implementation("org.jetbrains.kotlin:kotlin-script-runtime:1.9.20") api ("net.cactusthorn.config:config-core:0.81") kapt("net.cactusthorn.config:config-compiler:0.81") kapt("io.ebean:kotlin-querybean-generator:13.23.2") diff --git a/src/main/kotlin/com/restapi/controllers/Entities.kt b/src/main/kotlin/com/restapi/controllers/Entities.kt index f699ef6..ac00875 100644 --- a/src/main/kotlin/com/restapi/controllers/Entities.kt +++ b/src/main/kotlin/com/restapi/controllers/Entities.kt @@ -57,7 +57,8 @@ object Entities { val name = ctx.pathParam("name") val params = ctx.bodyAsClass>() ctx.json( - Scripting.execute(name, params) + Scripting. + execute(name, "execute", params, logger) ) } @@ -202,6 +203,12 @@ object Entities { } } } + if (!setupEntity.preSaveScript.isNullOrEmpty()) { + val ok = Scripting.preSave(setupEntity.preSaveScript!!, "preSave", this, logger) as Boolean + if (!ok) { + throw BadRequestResponse("PreSave Failed") + } + } if (setupEntity.approvalLevels > 0) { @@ -210,7 +217,8 @@ object Entities { } } - }) + } + ) } private fun isValidDate(f: String) = try { diff --git a/src/main/kotlin/com/restapi/integ/Scripting.kt b/src/main/kotlin/com/restapi/integ/Scripting.kt index ed0cb0a..16ea840 100644 --- a/src/main/kotlin/com/restapi/integ/Scripting.kt +++ b/src/main/kotlin/com/restapi/integ/Scripting.kt @@ -1,17 +1,29 @@ package com.restapi.integ import com.restapi.config.AppConfig.Companion.appConfig +import com.restapi.domain.DataModel +import com.restapi.domain.Session +import org.slf4j.Logger import java.io.File +import java.util.concurrent.ConcurrentHashMap import javax.script.Invocable import javax.script.ScriptEngineManager object Scripting { + private val engineMap = ConcurrentHashMap() - fun execute(name: String, params: Map): Any { + private fun getEngine(scriptName: String) = engineMap.computeIfAbsent(scriptName) { val engine = ScriptEngineManager().getEngineByExtension("kts")!! - engine.eval(File(appConfig.scriptsPath(), "$name.kts").reader()) - val invocator = engine as Invocable - return invocator.invokeFunction("execute", params) + engine.eval(File(appConfig.scriptsPath(), scriptName).reader()) + engine as Invocable + } + + fun execute(scriptName: String, fnName: String, params: Map, logger: Logger): Any { + return getEngine(scriptName).invokeFunction(fnName, params, Session.database, logger) + } + + fun preSave(scriptName: String, fnName: String, data: DataModel, logger: Logger): Any { + return getEngine(scriptName).invokeFunction(fnName, data, Session.database, logger) } } \ No newline at end of file diff --git a/src/main/resources/dbmigration/1.0.1__initial_data.sql b/src/main/resources/dbmigration/1.0.1__initial_data.sql index 4204d8f..289f5f4 100644 --- a/src/main/resources/dbmigration/1.0.1__initial_data.sql +++ b/src/main/resources/dbmigration/1.0.1__initial_data.sql @@ -1,2 +1,4 @@ -insert into tenant_model(name, domain, created_by, modified_by) values ('compegence', 'https://www.compegence.com', 'system', 'system'); -insert into entity_model(name, tenant_id, created_by, modified_by) values ('vehicle', 'compegence', 'system', 'system'); \ No newline at end of file +insert into tenant_model(name, domain, created_by, modified_by) + values ('compegence', 'https://www.compegence.com', 'system', 'system'); +insert into entity_model(name, tenant_id, created_by, modified_by, pre_save_script, post_save_script) + values ('vehicle', 'compegence', 'system', 'system', 'vehicle.kts', 'vehicle.kts'); \ No newline at end of file diff --git a/src/main/resources/scripts/vehicle.kts b/src/main/resources/scripts/vehicle.kts new file mode 100644 index 0000000..7caa371 --- /dev/null +++ b/src/main/resources/scripts/vehicle.kts @@ -0,0 +1,17 @@ +import com.restapi.domain.DataModel +import io.ebean.Database +import org.slf4j.Logger + +fun execute(d: Map, db: Database, logger: Logger): Map { + println("execute on $d") + return d +} + +fun preSave(d: DataModel, db: Database, logger: Logger): Boolean { + logger.warn("PreSave $d") + return true +} + +fun postSave(d: DataModel, db: Database, logger: Logger) { + println("PostSave $d") +} \ No newline at end of file