summaryrefslogtreecommitdiffstats
path: root/components/core/src/main
diff options
context:
space:
mode:
authorMuthuramalingam, Brinda Santh <bs2796@att.com>2019-01-11 11:30:40 -0500
committerMuthuramalingam, Brinda Santh <bs2796@att.com>2019-01-14 11:21:09 -0500
commit3f215fdd8239c8a32614d84c5b2dab518dbc819c (patch)
tree553329c59707a2d338af491de743a28e85755bdb /components/core/src/main
parenta8588a4aab5ff95890b9ad9ae1bc02a2043fab54 (diff)
Add blueprint Kotlin script support.
Change-Id: I92b8e9850ea07c7f671e7aada9770713854534c3 Issue-ID: CCSDK-941 Signed-off-by: Muthuramalingam, Brinda Santh <bs2796@att.com>
Diffstat (limited to 'components/core/src/main')
-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
4 files changed, 274 insertions, 0 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