summaryrefslogtreecommitdiffstats
path: root/components/core/src
diff options
context:
space:
mode:
authorDan Timoney <dtimoney@att.com>2019-01-16 21:00:38 +0000
committerGerrit Code Review <gerrit@onap.org>2019-01-16 21:00:38 +0000
commit527ac3b1022f30b053267773b43f59d936ef864e (patch)
tree4efb2a9c971b47d187ce3673c409eccb27745fb3 /components/core/src
parent554a351a8e0e94a96017a21911d27f48465d2beb (diff)
parent3f215fdd8239c8a32614d84c5b2dab518dbc819c (diff)
Merge "Add blueprint Kotlin script support."
Diffstat (limited to 'components/core/src')
-rw-r--r--components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptConfiguration.kt86
-rw-r--r--components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptService.kt78
-rw-r--r--components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BlueprintScriptingHost.kt93
-rw-r--r--components/core/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory17
-rw-r--r--components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptServiceTest.kt49
-rw-r--r--components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonReactorUtilsTest.kt52
-rw-r--r--components/core/src/test/resources/scripts/SampleBlueprintFunctionNode.kts44
7 files changed, 367 insertions, 52 deletions
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 00000000..f7bfb857
--- /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 00000000..8ae09151
--- /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 00000000..bda20a44
--- /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 00000000..89838f44
--- /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 00000000..5c5ad3ba
--- /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 ad55c776..00000000
--- 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 00000000..44cc957d
--- /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