diff options
author | 2019-01-16 21:00:38 +0000 | |
---|---|---|
committer | 2019-01-16 21:00:38 +0000 | |
commit | b846a36d1a27193b48c4be7d9a7dc7a1a509b61b (patch) | |
tree | 92d7e267fe1763e8a60c61132efdf81978063a6e | |
parent | 0445f02d75d32e9b495953c80771c54ffb311618 (diff) | |
parent | a3450eb629c88e8fe7f2a0a2d9b241004fd45442 (diff) |
Merge "Add blueprint Kotlin script support."
12 files changed, 427 insertions, 58 deletions
diff --git a/components/core/pom.xml b/components/core/pom.xml index 84063fd57..f33146b6a 100644 --- a/components/core/pom.xml +++ b/components/core/pom.xml @@ -63,6 +63,11 @@ <artifactId>mockk</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.jetbrains.kotlinx</groupId> + <artifactId>kotlinx-coroutines-test</artifactId> + <scope>test</scope> + </dependency> </dependencies> </project> diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptConfiguration.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptConfiguration.kt new file mode 100644 index 000000000..f7bfb857c --- /dev/null +++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptConfiguration.kt @@ -0,0 +1,86 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.apps.controllerblueprints.core.script + +import org.jetbrains.kotlin.script.util.LocalFilesResolver +import java.io.File +import kotlin.script.dependencies.ScriptContents +import kotlin.script.dependencies.ScriptDependenciesResolver +import kotlin.script.experimental.annotations.KotlinScript +import kotlin.script.experimental.api.* +import kotlin.script.experimental.jvm.JvmDependency +import kotlin.script.experimental.jvm.dependenciesFromCurrentContext +import kotlin.script.experimental.jvm.jvm + + +@KotlinScript(fileExtension = "kts", + compilationConfiguration = ComponentScriptConfiguration::class) +abstract class ComponentScript { + +} + +object ComponentScriptConfiguration : ScriptCompilationConfiguration( + { + // defaultImports(DependsOn::class, Repository::class) + jvm { + dependenciesFromCurrentContext( + wholeClasspath = true + ) + } +// refineConfiguration { +// onAnnotations(DependsOn::class, Repository::class, handler = ::configureLocalFileDepsOnAnnotations) +// } + } +) + + +private val resolver = LocalFilesResolver() + +fun configureLocalFileDepsOnAnnotations(context: ScriptConfigurationRefinementContext): + ResultWithDiagnostics<ScriptCompilationConfiguration> { + + val annotations = context.collectedData?.get(ScriptCollectedData.foundAnnotations)?.takeIf { it.isNotEmpty() } + ?: return context.compilationConfiguration.asSuccess() + + val scriptContents = object : ScriptContents { + override val annotations: Iterable<Annotation> = annotations + override val file: File? = null + override val text: CharSequence? = null + } + + val diagnostics = arrayListOf<ScriptDiagnostic>() + + fun report(severity: ScriptDependenciesResolver.ReportSeverity, message: String, position: ScriptContents.Position?) { + //TODO + } + + return try { + val newDepsFromResolver = resolver.resolve(scriptContents, emptyMap(), ::report, null).get() + ?: return context.compilationConfiguration.asSuccess(diagnostics) + + val resolvedClasspath = newDepsFromResolver.classpath.toList().takeIf { it.isNotEmpty() } + ?: return context.compilationConfiguration.asSuccess(diagnostics) + + ScriptCompilationConfiguration(context.compilationConfiguration) { + dependencies.append(JvmDependency(resolvedClasspath)) + + }.asSuccess(diagnostics) + + } catch (e: Throwable) { + ResultWithDiagnostics.Failure(*diagnostics.toTypedArray(), e.asDiagnostics()) + } +}
\ No newline at end of file diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptService.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptService.kt new file mode 100644 index 000000000..8ae091511 --- /dev/null +++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptService.kt @@ -0,0 +1,78 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.apps.controllerblueprints.core.script + +import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException +import java.io.File +import java.io.InputStream +import java.io.Reader +import javax.script.ScriptEngineManager +import kotlin.script.experimental.api.ResultValue +import kotlin.script.experimental.api.ResultWithDiagnostics +import kotlin.script.experimental.api.resultOrNull +import kotlin.script.experimental.host.toScriptSource +import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate + + +open class BluePrintScriptService(classLoader: ClassLoader? = Thread.currentThread().contextClassLoader) { + + /** + * Get the Script Class instance + */ + inline fun <reified T> scriptClassNewInstance(scriptFile: File, scriptClassName: String): T { + + val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<ComponentScript>() + + val scriptEvaluator = BluePrintScriptEvaluator(scriptClassName) + + val evalResponse = BlueprintScriptingHost(scriptEvaluator).eval(scriptFile.toScriptSource(), compilationConfiguration, + null) + + when (evalResponse) { + is ResultWithDiagnostics.Success -> { + val returnValue = evalResponse.resultOrNull()?.returnValue as ResultValue.Value + return returnValue.value.castOrError() + } + is ResultWithDiagnostics.Failure -> { + throw BluePrintProcessorException(evalResponse.reports.joinToString("\n")) + } + else -> { + throw BluePrintProcessorException("Failed to process script ${scriptFile.absolutePath}") + } + } + + } + + val engine = ScriptEngineManager(classLoader).getEngineByExtension("kts") + + inline fun <R> safeEval(evaluation: () -> R?) = try { + evaluation() + } catch (e: Exception) { + throw BluePrintProcessorException("Cannot load script", e) + } + + inline fun <reified T> Any?.castOrError() = takeIf { it is T }?.let { it as T } + ?: throw IllegalArgumentException("Cannot cast $this to expected type ${T::class}") + + inline fun <reified T> load(script: String): T = safeEval { engine.eval(script) }.castOrError() + + inline fun <reified T> load(reader: Reader): T = safeEval { engine.eval(reader) }.castOrError() + + inline fun <reified T> load(inputStream: InputStream): T = load(inputStream.reader()) + + inline fun <reified T> loadAll(vararg inputStream: InputStream): List<T> = inputStream.map(::load) +} diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BlueprintScriptingHost.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BlueprintScriptingHost.kt new file mode 100644 index 000000000..bda20a444 --- /dev/null +++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BlueprintScriptingHost.kt @@ -0,0 +1,93 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.apps.controllerblueprints.core.script + +import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException +import org.slf4j.LoggerFactory +import kotlin.script.experimental.api.* +import kotlin.script.experimental.host.BasicScriptingHost +import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration +import kotlin.script.experimental.jvmhost.JvmScriptCompiler + +val defaultBlueprintScriptCompiler = JvmScriptCompiler(defaultJvmScriptingHostConfiguration) + +open class BlueprintScriptingHost(evaluator: ScriptEvaluator +) : BasicScriptingHost(defaultBlueprintScriptCompiler, evaluator) { + + override fun eval( + script: SourceCode, + scriptCompilationConfiguration: ScriptCompilationConfiguration, + configuration: ScriptEvaluationConfiguration? + ): ResultWithDiagnostics<EvaluationResult> = + + runInCoroutineContext { + + compiler(script, scriptCompilationConfiguration) + .onSuccess { + evaluator(it, configuration) + } + } +} + + +open class BluePrintScriptEvaluator(private val scriptClassName: String) : ScriptEvaluator { + + val log = LoggerFactory.getLogger(BluePrintScriptEvaluator::class.java)!! + + override suspend operator fun invoke( + compiledScript: CompiledScript<*>, + scriptEvaluationConfiguration: ScriptEvaluationConfiguration? + ): ResultWithDiagnostics<EvaluationResult> = + try { + val res = compiledScript.getClass(scriptEvaluationConfiguration) + when (res) { + is ResultWithDiagnostics.Failure -> res + is ResultWithDiagnostics.Success -> { + val scriptClass = res.value + val args = ArrayList<Any?>() + scriptEvaluationConfiguration?.get(ScriptEvaluationConfiguration.providedProperties)?.forEach { + args.add(it.value) + } + scriptEvaluationConfiguration?.get(ScriptEvaluationConfiguration.implicitReceivers)?.let { + args.addAll(it) + } + scriptEvaluationConfiguration?.get(ScriptEvaluationConfiguration.constructorArgs)?.let { + args.addAll(it) + } + + val completeScriptClass = "Script\$$scriptClassName" + log.info("Searching for class type($completeScriptClass)") + /** + * Search for Class Name + */ + val instanceClass = scriptClass.java.classes + .single { it.name == completeScriptClass } + //.single { it.name == "Script\$SampleBlueprintsFunctionNode" } + + + val instance = instanceClass.newInstance() + ?: throw BluePrintProcessorException("failed to create instance from the script") + + ResultWithDiagnostics.Success(EvaluationResult(ResultValue.Value(completeScriptClass, + instance, instance.javaClass.typeName), + scriptEvaluationConfiguration)) + } + } + } catch (e: Throwable) { + ResultWithDiagnostics.Failure(e.asDiagnostics("Error evaluating script")) + } +}
\ No newline at end of file diff --git a/components/core/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory b/components/core/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory new file mode 100644 index 000000000..89838f44f --- /dev/null +++ b/components/core/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory @@ -0,0 +1,17 @@ +# +# Copyright © 2017-2018 AT&T Intellectual Property. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
\ No newline at end of file diff --git a/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptServiceTest.kt b/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptServiceTest.kt new file mode 100644 index 000000000..5c5ad3ba1 --- /dev/null +++ b/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptServiceTest.kt @@ -0,0 +1,49 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.apps.controllerblueprints.core.script + +import org.junit.Ignore +import org.junit.Test +import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BlueprintFunctionNode +import java.io.File +import kotlin.test.assertEquals +import kotlin.test.assertNotNull + +class BluePrintScriptServiceTest { + + @Test + fun `invoke script`() { + val scriptContent = "11 + 11" + val value = BluePrintScriptService() + .load<Int>(scriptContent) + assertEquals(22, value, "failed to execute command") + } + + @Test + @Ignore + fun `invoke script component node`() { + + //println(classpathFromClasspathProperty()?.joinToString("\n")) + + val scriptFile = File("src/test/resources/scripts/SampleBlueprintFunctionNode.kts") + + val functionNode = BluePrintScriptService() + .scriptClassNewInstance<BlueprintFunctionNode<String, String>>(scriptFile, + "SampleBlueprintFunctionNode") + assertNotNull(functionNode, "failed to get instance from script") + } +}
\ No newline at end of file diff --git a/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonReactorUtilsTest.kt b/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonReactorUtilsTest.kt deleted file mode 100644 index ad55c7761..000000000 --- a/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonReactorUtilsTest.kt +++ /dev/null @@ -1,52 +0,0 @@ -/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onap.ccsdk.apps.controllerblueprints.core.utils
-
-import com.att.eelf.configuration.EELFLogger
-import com.att.eelf.configuration.EELFManager
-import org.junit.Test
-import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
-import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate
-import kotlin.test.assertEquals
-import kotlin.test.assertNotNull
-
-@Deprecated("Reactor will be replacecd by coroutines by default.")
-class JacksonReactorUtilsTest {
- private val log: EELFLogger = EELFManager.getInstance().getLogger(this::class.toString())
- @Test
- fun testReadValues() {
-
- val serviceTemplate = JacksonReactorUtils.readValueFromFile("./../model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Definitions/activation-blueprint.json",
- ServiceTemplate::class.java).block()
-
- assertNotNull(serviceTemplate, "Failed to simple transform Service Template")
- assertEquals(true, serviceTemplate is ServiceTemplate, "failed to get Service Template instance")
-
- val jsonContent = JacksonReactorUtils.getJson(serviceTemplate, true).block()
- assertNotNull(jsonContent, "Failed to get json content")
-
- val jsonNode = JacksonReactorUtils.jsonNodeFromFile("./../model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Definitions/activation-blueprint.json")
- .block()
- assertNotNull(jsonContent, "Failed to get json Node")
- }
-
- @Test(expected = BluePrintException::class)
- fun testReadValuesFailure() {
- JacksonReactorUtils.jsonNodeFromFile("load/blueprints/not-found.json")
- .block()
- }
-}
\ No newline at end of file diff --git a/components/core/src/test/resources/scripts/SampleBlueprintFunctionNode.kts b/components/core/src/test/resources/scripts/SampleBlueprintFunctionNode.kts new file mode 100644 index 000000000..44cc957d2 --- /dev/null +++ b/components/core/src/test/resources/scripts/SampleBlueprintFunctionNode.kts @@ -0,0 +1,44 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BlueprintFunctionNode + +open class SampleBlueprintFunctionNode : BlueprintFunctionNode<String, String>{ + + override fun getName(): String { + return "Kotlin-Script-Function-Node" + } + + override fun prepareRequest(executionRequest: String): String { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun process(executionRequest: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun recover(runtimeException: RuntimeException, executionRequest: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun prepareResponse(): String { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun apply(t: String): String { + return "$t-status" + } +}
\ No newline at end of file diff --git a/components/model-catalog/definition-type/starter-type/artifact_type/artifact-script-kotlin.json b/components/model-catalog/definition-type/starter-type/artifact_type/artifact-script-kotlin.json new file mode 100644 index 000000000..cf19ac615 --- /dev/null +++ b/components/model-catalog/definition-type/starter-type/artifact_type/artifact-script-kotlin.json @@ -0,0 +1,8 @@ +{ + "description": "Kotlin Script file", + "version": "1.0.0", + "file_ext": [ + "kts" + ], + "derived_from": "tosca.artifacts.Implementation" +}
\ No newline at end of file diff --git a/components/model-catalog/definition-type/starter-type/node_type/source-capability.json b/components/model-catalog/definition-type/starter-type/node_type/source-capability.json index 241b69953..e4eb90e7b 100644 --- a/components/model-catalog/definition-type/starter-type/node_type/source-capability.json +++ b/components/model-catalog/definition-type/starter-type/node_type/source-capability.json @@ -5,10 +5,11 @@ "type": { "required": true, "type": "string", - "default": "JAVA-COMPONENT", + "default": "KOTLIN-COMPONENT", "constraints": [ { "valid_values": [ + "KOTLIN-COMPONENT", "JAVA-COMPONENT", "JYTHON-COMPONENT" ] diff --git a/components/model-catalog/definition-type/starter-type/node_type/tosca.nodes.component.Kotlin.json b/components/model-catalog/definition-type/starter-type/node_type/tosca.nodes.component.Kotlin.json new file mode 100644 index 000000000..381ed59e2 --- /dev/null +++ b/components/model-catalog/definition-type/starter-type/node_type/tosca.nodes.component.Kotlin.json @@ -0,0 +1,5 @@ +{ + "description": "This is Kotlin Component", + "version": "1.0.0", + "derived_from": "tosca.nodes.Root" +}
\ No newline at end of file diff --git a/components/parent/pom.xml b/components/parent/pom.xml index c9da403ca..8ecb2c1a2 100644 --- a/components/parent/pom.xml +++ b/components/parent/pom.xml @@ -31,13 +31,13 @@ <properties> <spring.boot.version>2.1.1.RELEASE</spring.boot.version> <spring.version>5.1.3.RELEASE</spring.version> - <kotlin.version>1.3.10</kotlin.version> - <kotlin.maven.version>1.3.10</kotlin.maven.version> - <kotlin.couroutines.version>1.0.1</kotlin.couroutines.version> - <grpc.version>1.16.1</grpc.version> + <kotlin.version>1.3.11</kotlin.version> + <kotlin.maven.version>1.3.11</kotlin.maven.version> + <kotlin.couroutines.version>1.1.0</kotlin.couroutines.version> + <grpc.version>1.17.1</grpc.version> <protobuff.java.utils.version>3.6.1</protobuff.java.utils.version> <eelf.version>1.0.0</eelf.version> - <guava.version>26.0-jre</guava.version> + <guava.version>27.0.1-jre</guava.version> <springfox.swagger2.version>2.9.2</springfox.swagger2.version> <h2database.version>1.4.197</h2database.version> <onap.logger.slf4j>1.2.2</onap.logger.slf4j> @@ -77,6 +77,7 @@ <version>${springfox.swagger2.version}</version> </dependency> + <!-- Common Utils Dependencies --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> @@ -115,6 +116,26 @@ <version>${kotlin.version}</version> </dependency> <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-scripting-jvm-host</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-compiler-embeddable</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-script-util</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-script-runtime</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-coroutines-core</artifactId> <version>${kotlin.couroutines.version}</version> @@ -202,6 +223,12 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.jetbrains.kotlinx</groupId> + <artifactId>kotlinx-coroutines-test</artifactId> + <version>${kotlin.couroutines.version}</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-testing</artifactId> <version>${grpc.version}</version> @@ -257,6 +284,10 @@ </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-script-util</artifactId> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk8</artifactId> </dependency> <dependency> @@ -271,6 +302,10 @@ <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-kotlin</artifactId> </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-scripting-jvm-host</artifactId> + </dependency> <!-- GRPC Dependencies --> <dependency> <groupId>io.grpc</groupId> |