diff options
author | Frank Kimmlingen <frank.kimmlingen@telekom.de> | 2024-01-09 16:01:14 +0100 |
---|---|---|
committer | Frank Kimmlingen <frank.kimmlingen@telekom.de> | 2024-01-09 16:01:14 +0100 |
commit | 5b924a33f2b7cd936aab934d706c8f735f7570d6 (patch) | |
tree | 4b97bf090ed429d40e6f5e27fad60296f1bad07e | |
parent | 72ae79d15d6ebc9a06202733b2fd999fb30ea048 (diff) |
During resource resolution there occurs from time to time a ConcurrentModificationException. This leads to errors, which are hard to find.
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
2 files changed, 22 insertions, 1 deletions
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt index 8087f7e3f..1710c4881 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt @@ -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" diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt index 36229b77e..88405f007 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt @@ -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>() |