During resource resolution there occurs from time to time a ConcurrentModificationExc... 51/136951/1
authorFrank Kimmlingen <frank.kimmlingen@telekom.de>
Tue, 9 Jan 2024 15:01:14 +0000 (16:01 +0100)
committerFrank Kimmlingen <frank.kimmlingen@telekom.de>
Tue, 9 Jan 2024 15:01:14 +0000 (16:01 +0100)
Simple solution is to use a ConcurrentHashMap instead, because this class is thread safe.

Issue-ID: CCSDK-3978
Signed-off-by: Frank Kimmlingen <frank.kimmlingen@telekom.de>
Change-Id: I68de3bc24d93a784964bc4b58caa2aeebf250e33

ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt

index 8087f7e..1710c48 100644 (file)
@@ -4,12 +4,13 @@ import com.fasterxml.jackson.databind.JsonNode
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
 import org.onap.ccsdk.cds.controllerblueprints.core.service.DefaultBluePrintRuntimeService
+import java.util.concurrent.ConcurrentHashMap
 
 class ResourceAssignmentRuntimeService(private var id: String, private var bluePrintContext: BluePrintContext) :
     DefaultBluePrintRuntimeService(id, bluePrintContext) {
 
     private lateinit var resolutionId: String
-    private var resourceStore: MutableMap<String, JsonNode> = hashMapOf()
+    private var resourceStore: MutableMap<String, JsonNode> = ConcurrentHashMap()
 
     fun createUniqueId(key: String) {
         resolutionId = "$id-$key"
index 36229b7..88405f0 100644 (file)
@@ -40,6 +40,8 @@ import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
+import java.util.concurrent.atomic.AtomicBoolean
+import kotlin.concurrent.thread
 import kotlin.test.assertEquals
 
 data class IpAddress(val port: String, val ip: String)
@@ -387,6 +389,24 @@ class ResourceAssignmentUtilsTest {
         )
     }
 
+    @Test
+    fun `resource resolution issue of resourceStore HashMap during resource resolution`() {
+        var uncaughtExceptionOccured = AtomicBoolean(false)
+        for (i in 1..1000) {
+            thread {
+                resourceAssignmentRuntimeService.putResolutionStore("key_$i", "value_$i".asJsonType())
+            }
+            val t = thread(false) {
+                resourceAssignmentRuntimeService.getResolutionStore()
+                // often ConcurrentModificationException occurs here
+            }
+            t.uncaughtExceptionHandler =
+                Thread.UncaughtExceptionHandler { t, e -> uncaughtExceptionOccured = AtomicBoolean(true) }
+            t.start()
+        }
+        assertEquals(uncaughtExceptionOccured.get(), false)
+    }
+
     private fun initInputMapAndExpectedValuesForPrimitiveType() {
         inputMapToTestPrimitiveTypeWithValue = "1.2.3.1".asJsonType()
         val keyValue = mutableMapOf<String, String>()