Fix kotlin cache lazy loading 78/102878/9
authorSebastien Premont-Tendland <sebastien.premont@bell.ca>
Mon, 2 Mar 2020 19:33:33 +0000 (14:33 -0500)
committerSebastien Premont-Tendland <sebastien.premont@bell.ca>
Thu, 19 Mar 2020 13:28:18 +0000 (13:28 +0000)
When USE_SCRIPT_COMPILATION_CACHE is set to false the classLoader
is closed after the class is instantiated. This is causing an issue
when lazy loading is happening during the script execution.

Lazy loading occurs when a suspendible function returning something
is called from "processNB", kotlin will create a second class that
will be loaded during execution (needs to be in the classpath during execution).

Issue-ID: CCSDK-2150

Signed-off-by: Sebastien Premont-Tendland <sebastien.premont@bell.ca>
Change-Id: I64780287352d762325662e0e5d5b94038dedee7f

ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt
ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BluePrintScriptsService.kt
ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintCompileService.kt
ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/scripts/BluePrintScriptsServiceImpl.kt
ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentFunctionScriptingService.kt
ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/ComponentScriptExecutor.kt

index 1262e85..307e73e 100644 (file)
@@ -65,6 +65,9 @@ open class ComponentNetconfExecutor(private var componentFunctionScriptingServic
 
         // Handles both script processing and error handling
         scriptComponent.executeScript(executionServiceInput)
+
+        componentFunctionScriptingService.cleanupInstance(bluePrintRuntimeService.bluePrintContext(),
+                scriptType)
     }
 
     override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
index d84488d..5fbe32e 100644 (file)
@@ -52,6 +52,10 @@ class CapabilityResourceResolutionProcessorTest {
                     .scriptInstance<ResourceAssignmentProcessor>(any(), any(), any())
             } returns MockCapabilityScriptRA()
 
+            coEvery {
+                componentFunctionScriptingService.cleanupInstance(any(), any())
+            } returns mockk()
+
             val raRuntimeService = mockk<ResourceAssignmentRuntimeService>()
             every { raRuntimeService.bluePrintContext() } returns mockk<BluePrintContext>()
             every { raRuntimeService.getInputValue("test-property") } returns NullNode.getInstance()
@@ -96,6 +100,10 @@ class CapabilityResourceResolutionProcessorTest {
                     .scriptInstance<ResourceAssignmentProcessor>(any(), BluePrintConstants.SCRIPT_JYTHON, any())
             } returns MockCapabilityScriptRA()
 
+            coEvery {
+                componentFunctionScriptingService.cleanupInstance(any(), any())
+            } returns mockk()
+
             val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService("1234", bluePrintContext)
 
             val capabilityResourceResolutionProcessor =
index a8c6303..a9684a1 100644 (file)
@@ -25,11 +25,9 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
 import org.jetbrains.kotlin.cli.common.messages.MessageCollector
 import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
 import org.jetbrains.kotlin.config.Services
-import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
 import org.onap.ccsdk.cds.controllerblueprints.core.checkFileExists
 import org.onap.ccsdk.cds.controllerblueprints.core.logger
-import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils
 import java.io.File
 import java.net.URLClassLoader
 import java.util.ArrayList
@@ -58,13 +56,7 @@ open class BluePrintCompileService {
             compile(bluePrintSourceCode)
         }
 
-        val classLoaderWithDependencies = if (BluePrintConstants.USE_SCRIPT_COMPILE_CACHE) {
-            /** Get the class loader with compiled jar from cache */
-            BluePrintCompileCache.classLoader(bluePrintSourceCode.cacheKey)
-        } else {
-            /** Get the class loader with compiled jar from disk */
-            BluePrintFileUtils.getURLClassLoaderFromDirectory(bluePrintSourceCode.cacheKey)
-        }
+        val classLoaderWithDependencies = BluePrintCompileCache.classLoader(bluePrintSourceCode.cacheKey)
 
         /** Create the instance from the class loader */
         return instance(classLoaderWithDependencies, kClassName, args)
@@ -126,9 +118,6 @@ open class BluePrintCompileService {
                 .single().newInstance(*args.toArray())
         } ?: throw BluePrintException("failed to create class($kClassName) instance for constructor argument($args).")
 
-        if (!BluePrintConstants.USE_SCRIPT_COMPILE_CACHE) {
-            classLoader.close()
-        }
         return instance as T
     }
 }
index f3eb1a2..fa8ca27 100644 (file)
@@ -79,4 +79,11 @@ open class BluePrintScriptsServiceImpl : BluePrintScriptsService {
         return Thread.currentThread().contextClassLoader.loadClass(scriptClassName).constructors
             .single().newInstance(*args.toArray()) as T
     }
+
+    override suspend fun cleanupInstance(blueprintBasePath: String) {
+        if (!BluePrintConstants.USE_SCRIPT_COMPILE_CACHE) {
+            log.info("Invalidating compile cache for blueprint ($blueprintBasePath)")
+            BluePrintCompileCache.cleanClassLoader(blueprintBasePath)
+        }
+    }
 }
index 4c7d5d0..34b1809 100644 (file)
@@ -101,4 +101,10 @@ class ComponentFunctionScriptingService(
         }
         return scriptComponent
     }
+
+    suspend fun cleanupInstance(bluePrintContext: BluePrintContext, scriptType: String) {
+        if (scriptType == BluePrintConstants.SCRIPT_KOTLIN) {
+            BluePrintScriptsServiceImpl().cleanupInstance(bluePrintContext.rootPath)
+        }
+    }
 }
index 09eee67..2a63297 100644 (file)
@@ -60,6 +60,8 @@ open class ComponentScriptExecutor(private var componentFunctionScriptingService
 
         // Handles both script processing and error handling
         scriptComponentFunction.executeScript(executionServiceInput)
+
+        componentFunctionScriptingService.cleanupInstance(bluePrintRuntimeService.bluePrintContext(), scriptType)
     }
 
     override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {