diff options
author | Dan Timoney <dtimoney@att.com> | 2019-01-28 19:15:36 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2019-01-28 19:15:36 +0000 |
commit | a0cd90bb6b219db81a680242c3c3b372a1f727f3 (patch) | |
tree | 80a056785e0a63a5e8dd658b62b4833cf4d76310 | |
parent | 263590df9d30640c02346ce913229fea8d8a2b6d (diff) | |
parent | d4332bfb76672ced58c0836b868ec1376ba89146 (diff) |
Merge "blueprint scripting module"
17 files changed, 590 insertions, 276 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 deleted file mode 100644 index f7bfb857..00000000 --- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptConfiguration.kt +++ /dev/null @@ -1,86 +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.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 deleted file mode 100644 index 8ae09151..00000000 --- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptService.kt +++ /dev/null @@ -1,78 +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.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/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 deleted file mode 100644 index 5c5ad3ba..00000000 --- a/components/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BluePrintScriptServiceTest.kt +++ /dev/null @@ -1,49 +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.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/parent/pom.xml b/components/parent/pom.xml index b53f9f11..6d5c2c14 100644 --- a/components/parent/pom.xml +++ b/components/parent/pom.xml @@ -29,11 +29,11 @@ <name>Components Parent</name> <packaging>pom</packaging> <properties> - <spring.boot.version>2.1.1.RELEASE</spring.boot.version> - <spring.version>5.1.3.RELEASE</spring.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> + <spring.boot.version>2.1.2.RELEASE</spring.boot.version> + <spring.version>5.1.4.RELEASE</spring.version> + <kotlin.version>1.3.20</kotlin.version> + <kotlin.maven.version>1.3.20</kotlin.maven.version> + <kotlin.couroutines.version>1.1.1</kotlin.couroutines.version> <grpc.version>1.18.0</grpc.version> <protobuff.java.utils.version>3.6.1</protobuff.java.utils.version> <eelf.version>1.0.0</eelf.version> @@ -307,22 +307,6 @@ <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-kotlin</artifactId> </dependency> - <dependency> - <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-compiler-embeddable</artifactId> - </dependency> - <dependency> - <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-scripting-jvm-host</artifactId> - <!--Use kotlin-compiler-embeddable as koltin-compiler wrap--> - <!--guava dependency creating classpath issues at runtime--> - <exclusions> - <exclusion> - <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-compiler</artifactId> - </exclusion> - </exclusions> - </dependency> <!-- GRPC Dependencies --> <dependency> <groupId>io.grpc</groupId> diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml index be187726..472b466b 100755 --- a/ms/blueprintsprocessor/parent/pom.xml +++ b/ms/blueprintsprocessor/parent/pom.xml @@ -31,11 +31,11 @@ <name>Blueprints Processor Parent</name> <description>Blueprints Processor Parent</description> <properties> - <spring.boot.version>2.1.1.RELEASE</spring.boot.version> - <spring.version>5.1.3.RELEASE</spring.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> + <spring.boot.version>2.1.2.RELEASE</spring.boot.version> + <spring.version>5.1.4.RELEASE</spring.version> + <kotlin.version>1.3.20</kotlin.version> + <kotlin.maven.version>1.3.20</kotlin.maven.version> + <kotlin.couroutines.version>1.1.1</kotlin.couroutines.version> <grpc.version>1.18.0</grpc.version> <protobuff.java.utils.version>3.6.1</protobuff.java.utils.version> <eelf.version>1.0.0</eelf.version> @@ -130,16 +130,23 @@ <artifactId>kotlin-stdlib-common</artifactId> <version>${kotlin.version}</version> </dependency> + <!--Use kotlin-compiler-embeddable instead koltin-compiler wrap--> + <!--guava dependency inside kotlin-compiler creating classpath issues at runtime--> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-scripting-jvm-host</artifactId> <version>${kotlin.version}</version> + <exclusions> + <exclusion> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-compile</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-compiler-embeddable</artifactId> <version>${kotlin.version}</version> - <scope>runtime</scope> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> diff --git a/ms/controllerblueprints/application/src/main/resources/application.properties b/ms/controllerblueprints/application/src/main/resources/application.properties index b6d509ce..ec61be48 100755 --- a/ms/controllerblueprints/application/src/main/resources/application.properties +++ b/ms/controllerblueprints/application/src/main/resources/application.properties @@ -41,7 +41,7 @@ spring.jpa.properties.hibernate.use_sql_comments=true spring.jpa.properties.hibernate.format_sql=true # spring.datasource.url, spring.datasource.username,spring.datasource.password may be overridden by ENV variables -spring.datasource.url=jdbc:mysql://db:3306/sdnctl +spring.datasource.url=jdbc:mysql://localhost:3306/sdnctl spring.datasource.username=sdnctl spring.datasource.password=sdnctl spring.datasource.driver-class-name=org.mariadb.jdbc.Driver diff --git a/ms/controllerblueprints/modules/blueprint-scripts/pom.xml b/ms/controllerblueprints/modules/blueprint-scripts/pom.xml new file mode 100644 index 00000000..46c88b4c --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-scripts/pom.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>modules</artifactId> + <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> + <version>0.4.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>blueprint-scripts</artifactId> + <name>Controller Blueprints Scripts</name> + + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> + <artifactId>resource-dict</artifactId> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-compiler-embeddable</artifactId> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-scripting-jvm-host</artifactId> + <exclusions> + <exclusion> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-compiler</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-script-util</artifactId> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-script-runtime</artifactId> + </dependency> + </dependencies> + +</project>
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BluePrintCompiledScript.kt b/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BluePrintCompiledScript.kt new file mode 100644 index 00000000..8ac915bd --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BluePrintCompiledScript.kt @@ -0,0 +1,56 @@ +/* + * 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.scripts + +import java.io.File +import java.io.Serializable +import java.net.URL +import java.net.URLClassLoader +import kotlin.reflect.KClass +import kotlin.script.experimental.api.* + +open class BluePrintCompiledScript<out JarFile : File>( + private val scriptCompilationConfiguration: ScriptCompilationConfiguration, + private val compiledJar: File) : + CompiledScript<JarFile>, Serializable { + + lateinit var scriptClassFQName: String + + override val compilationConfiguration: ScriptCompilationConfiguration + get() = scriptCompilationConfiguration + + override suspend fun getClass(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?): ResultWithDiagnostics<KClass<*>> = try { + + val baseClassLoader = Thread.currentThread().contextClassLoader + + val urls = arrayListOf<URL>() + urls.add(compiledJar.toURI().toURL()) + val classLoaderWithDependencies = URLClassLoader(urls.toTypedArray(), baseClassLoader) + + val clazz = classLoaderWithDependencies.loadClass(scriptClassFQName).kotlin + clazz.asSuccess() + } catch (e: Throwable) { + ResultWithDiagnostics.Failure( + ScriptDiagnostic( + "Unable to instantiate class $scriptClassFQName", + exception = e + ) + ) + } + +} + diff --git a/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BluePrintCompilerProxy.kt b/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BluePrintCompilerProxy.kt new file mode 100644 index 00000000..7e9e8688 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BluePrintCompilerProxy.kt @@ -0,0 +1,150 @@ +/* + * 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.scripts + +import org.jetbrains.kotlin.com.intellij.openapi.util.Disposer +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoots +import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback +import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler +import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot +import org.jetbrains.kotlin.config.* +import org.slf4j.LoggerFactory +import java.io.File +import kotlin.script.experimental.api.* +import kotlin.script.experimental.host.ScriptingHostConfiguration +import kotlin.script.experimental.jvm.util.classpathFromClasspathProperty +import kotlin.script.experimental.jvmhost.KJvmCompilerProxy + +open class BluePrintsCompilerProxy(private val hostConfiguration: ScriptingHostConfiguration) : KJvmCompilerProxy { + + private val log = LoggerFactory.getLogger(BluePrintsCompilerProxy::class.java)!! + + override fun compile(script: SourceCode, scriptCompilationConfiguration: ScriptCompilationConfiguration) + : ResultWithDiagnostics<CompiledScript<*>> { + + val messageCollector = ScriptDiagnosticsMessageCollector() + + fun failure(vararg diagnostics: ScriptDiagnostic): ResultWithDiagnostics.Failure = + ResultWithDiagnostics.Failure(*messageCollector.diagnostics.toTypedArray(), *diagnostics) + + // Compile the Code + try { + + log.trace("Scripting Host Configuration : $hostConfiguration") + + setIdeaIoUseFallback() + + val blueprintSourceCode = script as BluePrintSourceCode + + val compiledJarFile = blueprintSourceCode.targetJarFile + + if (!compiledJarFile.exists() || blueprintSourceCode.regenerate) { + + var environment: KotlinCoreEnvironment? = null + + val rootDisposable = Disposer.newDisposable() + + val compilerConfiguration = CompilerConfiguration().apply { + + put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) + put(CommonConfigurationKeys.MODULE_NAME, blueprintSourceCode.moduleName) + put(JVMConfigurationKeys.OUTPUT_JAR, compiledJarFile) + put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, false) + + // Load Current Class loader to Compilation Class loader + val currentClassLoader = classpathFromClasspathProperty() + currentClassLoader?.forEach { + add(CLIConfigurationKeys.CONTENT_ROOTS, JvmClasspathRoot(it)) + } + + // Add all Kotlin Sources + addKotlinSourceRoots(blueprintSourceCode.blueprintKotlinSources) + + languageVersionSettings = LanguageVersionSettingsImpl( + LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, mapOf(AnalysisFlags.skipMetadataVersionCheck to true) + ) + } + + //log.info("Executing with compiler configuration : $compilerConfiguration") + + environment = KotlinCoreEnvironment.createForProduction(rootDisposable, compilerConfiguration, + EnvironmentConfigFiles.JVM_CONFIG_FILES) + + // Compile Kotlin Sources + val compiled = KotlinToJVMBytecodeCompiler.compileBunchOfSources(environment) + + log.info("Generated jar(${compiledJarFile.absolutePath}) status : $compiled}") + + val analyzerWithCompilerReport = AnalyzerWithCompilerReport(messageCollector, + environment.configuration.languageVersionSettings) + + if (analyzerWithCompilerReport.hasErrors()) { + return failure() + } + } + + val res = BluePrintCompiledScript<File>(scriptCompilationConfiguration, compiledJarFile) + + return ResultWithDiagnostics.Success(res, messageCollector.diagnostics) + + } catch (ex: Throwable) { + return failure(ex.asDiagnostics()) + } + } +} + +class ScriptDiagnosticsMessageCollector : MessageCollector { + + private val _diagnostics = arrayListOf<ScriptDiagnostic>() + + val diagnostics: List<ScriptDiagnostic> get() = _diagnostics + + override fun clear() { + _diagnostics.clear() + } + + override fun hasErrors(): Boolean = + _diagnostics.any { it.severity == ScriptDiagnostic.Severity.ERROR } + + + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) { + val mappedSeverity = when (severity) { + CompilerMessageSeverity.EXCEPTION, + CompilerMessageSeverity.ERROR -> ScriptDiagnostic.Severity.ERROR + CompilerMessageSeverity.STRONG_WARNING, + CompilerMessageSeverity.WARNING -> ScriptDiagnostic.Severity.WARNING + CompilerMessageSeverity.INFO -> ScriptDiagnostic.Severity.INFO + CompilerMessageSeverity.LOGGING -> ScriptDiagnostic.Severity.DEBUG + else -> null + } + if (mappedSeverity != null) { + val mappedLocation = location?.let { + if (it.line < 0 && it.column < 0) null // special location created by CompilerMessageLocation.create + else SourceCode.Location(SourceCode.Position(it.line, it.column)) + } + _diagnostics.add(ScriptDiagnostic(message, mappedSeverity, location?.path, mappedLocation)) + } + } +} + diff --git a/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BluePrintScriptConfiguration.kt b/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BluePrintScriptConfiguration.kt new file mode 100644 index 00000000..3b3a5907 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BluePrintScriptConfiguration.kt @@ -0,0 +1,61 @@ +/* + * 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.scripts + +import java.io.File +import kotlin.script.experimental.annotations.KotlinScript +import kotlin.script.experimental.api.ScriptCompilationConfiguration +import kotlin.script.experimental.api.SourceCode +import kotlin.script.experimental.api.defaultImports +import kotlin.script.experimental.jvm.jvm +import kotlin.script.experimental.jvm.util.classpathFromClassloader + +@KotlinScript( + fileExtension = "cba.kts", + compilationConfiguration = BluePrintScripCompilationConfiguration::class, + displayName = "Controller Blueprint Archive Kotlin Scripts" +) +abstract class BluePrintKotlinScript + +object BluePrintScripCompilationConfiguration : ScriptCompilationConfiguration( + { + defaultImports( + "org.onap.ccsdk.apps.controllerblueprints.core.*", + "org.onap.ccsdk.apps.controllerblueprints.core.data.*", + "org.onap.ccsdk.apps.controllerblueprints.core.interfaces.*", + "org.onap.ccsdk.apps.controllerblueprints.core.services.*", + "org.onap.ccsdk.apps.controllerblueprints.core.utils.*") + jvm { + classpathFromClassloader(BluePrintScripCompilationConfiguration::class.java.classLoader) + } + } +) + +open class BluePrintSourceCode : SourceCode { + lateinit var blueprintKotlinSources: MutableList<String> + lateinit var moduleName: String + lateinit var targetJarFile: File + var regenerate: Boolean = false + + override val text: String + get() = "" + + override val locationId: String? = null + + override val name: String? + get() = moduleName +} diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BlueprintScriptingHost.kt b/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BlueprintScriptingHost.kt index bda20a44..59ce4abb 100644 --- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/script/BlueprintScriptingHost.kt +++ b/ms/controllerblueprints/modules/blueprint-scripts/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BlueprintScriptingHost.kt @@ -14,19 +14,21 @@ * limitations under the License. */ -package org.onap.ccsdk.apps.controllerblueprints.core.script +package org.onap.ccsdk.apps.controllerblueprints.scripts import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException import org.slf4j.LoggerFactory +import java.util.* import kotlin.script.experimental.api.* import kotlin.script.experimental.host.BasicScriptingHost import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration import kotlin.script.experimental.jvmhost.JvmScriptCompiler +import kotlin.script.experimental.jvmhost.impl.withDefaults -val defaultBlueprintScriptCompiler = JvmScriptCompiler(defaultJvmScriptingHostConfiguration) +val blueprintScriptCompiler = JvmScriptCompiler(defaultJvmScriptingHostConfiguration, + BluePrintsCompilerProxy(defaultJvmScriptingHostConfiguration.withDefaults())) -open class BlueprintScriptingHost(evaluator: ScriptEvaluator -) : BasicScriptingHost(defaultBlueprintScriptCompiler, evaluator) { +open class BlueprintScriptingHost(evaluator: ScriptEvaluator) : BasicScriptingHost(blueprintScriptCompiler, evaluator) { override fun eval( script: SourceCode, @@ -44,19 +46,24 @@ open class BlueprintScriptingHost(evaluator: ScriptEvaluator } -open class BluePrintScriptEvaluator(private val scriptClassName: String) : ScriptEvaluator { +open class BluePrintScriptEvaluator<T>(private val scriptClassName: String) : ScriptEvaluator { - val log = LoggerFactory.getLogger(BluePrintScriptEvaluator::class.java)!! + private val log = LoggerFactory.getLogger(BluePrintScriptEvaluator::class.java)!! override suspend operator fun invoke( compiledScript: CompiledScript<*>, scriptEvaluationConfiguration: ScriptEvaluationConfiguration? ): ResultWithDiagnostics<EvaluationResult> = try { + log.info("Getting class name($scriptClassName) of type() from the compiled sources ") + val bluePrintCompiledScript = compiledScript as BluePrintCompiledScript + bluePrintCompiledScript.scriptClassFQName = scriptClassName + 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 { @@ -69,21 +76,13 @@ open class BluePrintScriptEvaluator(private val scriptClassName: String) : Scrip 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() + val instance = scriptClass.java.newInstance() as? T ?: throw BluePrintProcessorException("failed to create instance from the script") - ResultWithDiagnostics.Success(EvaluationResult(ResultValue.Value(completeScriptClass, - instance, instance.javaClass.typeName), + log.info("Created script instance successfully....") + + ResultWithDiagnostics.Success(EvaluationResult(ResultValue.Value(scriptClass.qualifiedName!!, + instance, "", instance), scriptEvaluationConfiguration)) } } diff --git a/ms/controllerblueprints/modules/blueprint-scripts/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BlueprintScriptingHostTest.kt b/ms/controllerblueprints/modules/blueprint-scripts/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BlueprintScriptingHostTest.kt new file mode 100644 index 00000000..4b6f2a47 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-scripts/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/scripts/BlueprintScriptingHostTest.kt @@ -0,0 +1,88 @@ +/* + * 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.scripts + + +import org.apache.commons.io.FileUtils +import org.junit.Ignore +import org.junit.Test +import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BlueprintFunctionNode +import java.io.File +import kotlin.script.experimental.jvm.util.classpathFromClass +import kotlin.script.experimental.jvm.util.classpathFromClassloader +import kotlin.script.experimental.jvm.util.classpathFromClasspathProperty +import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate + +class BlueprintScriptingHostTest { + + @Test + @Ignore + fun `test classpaths`() { + + println(" *********** classpathFromClass *********** ") + classpathFromClass(BlueprintScriptingHostTest::class.java.classLoader, + BlueprintScriptingHostTest::class)!! + .forEach(::println) + + println(" *********** classpathFromClassloader *********** ") + classpathFromClassloader(BlueprintScriptingHostTest::class.java.classLoader)!! + .forEach(::println) + + println(" *********** classpathFromClasspathProperty *********** ") + classpathFromClasspathProperty()!! + .forEach(::println) + } + + @Test + fun `test same script two folders`() { + + FileUtils.forceMkdir(File("target/scripts1/")) + FileUtils.forceMkdir(File("target/scripts2/")) + + val scriptSource1 = BluePrintSourceCode() + scriptSource1.moduleName = "blueprint-test-script" + + scriptSource1.targetJarFile = File("target/scripts1/blueprint-script-generated.jar") + val sources1: MutableList<String> = arrayListOf() + sources1.add("src/test/resources/scripts1") + scriptSource1.blueprintKotlinSources = sources1 + + val scriptClassName = "Simple_cba\$SampleComponentFunction" + + val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<BluePrintKotlinScript>() + + val scriptEvaluator = BluePrintScriptEvaluator<BlueprintFunctionNode<String, String>>(scriptClassName) + + val scriptSource2 = BluePrintSourceCode() + scriptSource2.moduleName = "blueprint-test-script" + + scriptSource2.targetJarFile = File("target/scripts2/blueprint-script-generated.jar") + val sources2: MutableList<String> = arrayListOf() + sources2.add("src/test/resources/scripts2") + scriptSource2.blueprintKotlinSources = sources2 + + for (i in 1..2) { + val evalResponse = BlueprintScriptingHost(scriptEvaluator).eval(scriptSource1, compilationConfiguration, + null) + } + + for (i in 1..2) { + val evalResponse = BlueprintScriptingHost(scriptEvaluator).eval(scriptSource2, compilationConfiguration, + null) + } + } +}
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-scripts/src/test/resources/scripts1/simple.cba.kts b/ms/controllerblueprints/modules/blueprint-scripts/src/test/resources/scripts1/simple.cba.kts new file mode 100644 index 00000000..9f61c649 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-scripts/src/test/resources/scripts1/simple.cba.kts @@ -0,0 +1,55 @@ +/* + * 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.asJsonPrimitive +import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate +import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BlueprintFunctionNode +import org.springframework.stereotype.Service + +@Service +open class SampleComponentFunction : BlueprintFunctionNode<String, String> { + + override fun getName(): String { + println("Printing Name....." + "sample".asJsonPrimitive()) + return "my Name" + } + + 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 "Script 1 response - $t" + } +} + +val blueprintFunction = SampleComponentFunction() + +val serviceTemplate = ServiceTemplate() + +println("Simple script printing....") diff --git a/ms/controllerblueprints/modules/blueprint-scripts/src/test/resources/scripts2/simple.cba.kts b/ms/controllerblueprints/modules/blueprint-scripts/src/test/resources/scripts2/simple.cba.kts new file mode 100644 index 00000000..84517254 --- /dev/null +++ b/ms/controllerblueprints/modules/blueprint-scripts/src/test/resources/scripts2/simple.cba.kts @@ -0,0 +1,55 @@ +/* + * 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.asJsonPrimitive +import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate +import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BlueprintFunctionNode +import org.springframework.stereotype.Service + +@Service +open class SampleComponentFunction : BlueprintFunctionNode<String, String> { + + override fun getName(): String { + println("Printing Name....." + "sample".asJsonPrimitive()) + return "my Name" + } + + 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 "Script 2 response - $t" + } +} + +val blueprintFunction = SampleComponentFunction() + +val serviceTemplate = ServiceTemplate() + +println("Simple script printing....") diff --git a/ms/controllerblueprints/modules/pom.xml b/ms/controllerblueprints/modules/pom.xml index 3857ef5d..834db24e 100644 --- a/ms/controllerblueprints/modules/pom.xml +++ b/ms/controllerblueprints/modules/pom.xml @@ -30,6 +30,7 @@ <module>service</module> <module>blueprint-validation</module> <module>db-resources</module> + <module>blueprint-scripts</module> </modules> <build> diff --git a/ms/controllerblueprints/modules/service/pom.xml b/ms/controllerblueprints/modules/service/pom.xml index 9868b17b..73fe0739 100644 --- a/ms/controllerblueprints/modules/service/pom.xml +++ b/ms/controllerblueprints/modules/service/pom.xml @@ -32,10 +32,6 @@ <dependencies> <dependency> <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> - <artifactId>core</artifactId> - </dependency> - <dependency> - <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> <artifactId>db-resources</artifactId> </dependency> <dependency> @@ -44,7 +40,7 @@ </dependency> <dependency> <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> - <artifactId>resource-dict</artifactId> + <artifactId>blueprint-scripts</artifactId> </dependency> <dependency> <groupId>org.apache.velocity</groupId> diff --git a/ms/controllerblueprints/parent/pom.xml b/ms/controllerblueprints/parent/pom.xml index 578a0c7e..8cbc98e0 100644 --- a/ms/controllerblueprints/parent/pom.xml +++ b/ms/controllerblueprints/parent/pom.xml @@ -28,11 +28,11 @@ <name>Controller Blueprints Parent</name> <packaging>pom</packaging> <properties> - <spring.boot.version>2.1.1.RELEASE</spring.boot.version> - <spring.version>5.1.3.RELEASE</spring.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> + <spring.boot.version>2.1.2.RELEASE</spring.boot.version> + <spring.version>5.1.4.RELEASE</spring.version> + <kotlin.version>1.3.20</kotlin.version> + <kotlin.maven.version>1.3.20</kotlin.maven.version> + <kotlin.couroutines.version>1.1.1</kotlin.couroutines.version> <grpc.version>1.18.0</grpc.version> <protobuff.java.utils.version>3.6.1</protobuff.java.utils.version> <eelf.version>1.0.0</eelf.version> @@ -113,16 +113,23 @@ <artifactId>kotlin-stdlib-common</artifactId> <version>${kotlin.version}</version> </dependency> + <!--Use kotlin-compiler-embeddable instead koltin-compiler wrap--> + <!--guava dependency inside kotlin-compiler creating classpath issues at runtime--> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-scripting-jvm-host</artifactId> <version>${kotlin.version}</version> + <exclusions> + <exclusion> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-compile</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-compiler-embeddable</artifactId> <version>${kotlin.version}</version> - <scope>runtime</scope> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> @@ -203,27 +210,32 @@ </dependency> <dependency> <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> - <artifactId>service</artifactId> + <artifactId>resource-dict</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> - <artifactId>application</artifactId> + <artifactId>db-resources</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> - <artifactId>resource-dict</artifactId> + <artifactId>blueprint-validation</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> - <artifactId>db-resources</artifactId> + <artifactId>blueprint-scripts</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> - <artifactId>blueprint-validation</artifactId> + <artifactId>service</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId> + <artifactId>application</artifactId> <version>${project.version}</version> </dependency> @@ -275,6 +287,10 @@ <artifactId>json-path</artifactId> </dependency> <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> </dependency> |