summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt12
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt62
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt48
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt22
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt189
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/test/resources/payload/requests/sample-resourceresolution-request2.json31
6 files changed, 356 insertions, 8 deletions
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt
index e060cdcc5..d46f75e41 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt
@@ -109,9 +109,13 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re
val artifactPrefixNamesNode = getOperationInput(ResourceResolutionConstants.INPUT_ARTIFACT_PREFIX_NAMES)
val artifactPrefixNames = JacksonUtils.getListFromJsonNode(artifactPrefixNamesNode, String::class.java)
+ val alwaysPerformNewResolution = occurrence <= 0
+ val resolutionsToPerform: Int = if (alwaysPerformNewResolution) 1 else occurrence
+ for (j in 1..resolutionsToPerform) {
- for (j in 1..occurrence) {
- properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = j
+ if (!alwaysPerformNewResolution) {
+ properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = j
+ }
val result = resourceResolutionService.resolveResources(
bluePrintRuntimeService,
@@ -121,8 +125,8 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re
stepName
)
- // provide indexed result in output if we have multiple resolution
- if (occurrence != 1) {
+ // provide indexed result in output if we have multiple resolution.
+ if (resolutionsToPerform != 1) {
jsonResponse.set<JsonNode>(j.toString(), result.templateMap.asJsonNode())
assignmentMap.set<JsonNode>(j.toString(), result.assignmentMap.asJsonNode())
} else {
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
index 8923a1143..a3c137807 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
@@ -201,6 +201,7 @@ open class ResourceResolutionServiceImpl(
val artifactMapping = "$artifactPrefix-mapping"
val forceResolution = isForceResolution(properties)
+ val propertiesMutableMap = properties.toMutableMap()
log.info("Resolving resource with resource assignment artifact($artifactMapping)")
val resourceAssignmentContent =
@@ -212,7 +213,16 @@ open class ResourceResolutionServiceImpl(
?: throw BluePrintProcessorException("couldn't get Dictionary Definitions")
if (isToStore(properties)) {
- val existingResourceResolution = isNewResolution(bluePrintRuntimeService, properties, artifactPrefix)
+ val alwaysPerformNewResolution = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int <= 0
+ val existingResourceResolution = if (alwaysPerformNewResolution) {
+ val occurrence = findNextOccurrence(bluePrintRuntimeService, properties, artifactPrefix)
+ log.info("Always perform new resolutions - next occurrence: $occurrence")
+ propertiesMutableMap[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence
+ // Since we are performing new resolution, simply pass empty list.
+ emptyList()
+ } else {
+ isNewResolution(bluePrintRuntimeService, properties, artifactPrefix)
+ }
if (existingResourceResolution.isNotEmpty()) {
if (forceResolution) {
resourceResolutionDBService.deleteResourceResolutionList(existingResourceResolution)
@@ -237,7 +247,7 @@ open class ResourceResolutionServiceImpl(
resourceDefinitions,
resourceAssignments,
artifactPrefix,
- properties
+ propertiesMutableMap
)
val resolutionSummary = properties.getOrDefault(
@@ -271,7 +281,7 @@ open class ResourceResolutionServiceImpl(
}
if (isToStore(properties)) {
- templateResolutionDBService.write(properties, resolvedContent, bluePrintRuntimeService, artifactPrefix)
+ templateResolutionDBService.write(propertiesMutableMap, resolvedContent, bluePrintRuntimeService, artifactPrefix)
log.info("Template resolution saved into database successfully : ($properties)")
}
@@ -490,7 +500,7 @@ open class ResourceResolutionServiceImpl(
}
}
- // Comparision between what we have in the database vs what we have to assign.
+ // Comparison between what we have in the database vs what we have to assign.
private fun compareOne(resourceResolution: ResourceResolution, resourceAssignment: ResourceAssignment): Boolean {
return (
resourceResolution.name == resourceAssignment.name &&
@@ -509,4 +519,48 @@ open class ResourceResolutionServiceImpl(
properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE].asJsonPrimitive()
)
}
+
+ /**
+ * This method returns 'occurrence' required to persist new resource resolution.
+ *
+ * @param bluePrintRuntimeService
+ * @param properties
+ * @param artifactPrefix
+ */
+ private suspend fun findNextOccurrence(
+ bluePrintRuntimeService: BluePrintRuntimeService<*>,
+ properties: Map<String, Any>,
+ artifactPrefix: String
+ ): Int {
+ val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
+ val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
+ val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
+ val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] as String
+ val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String
+ val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String
+
+ // This should not happen since the request has already been validated but worth to check it here as well.
+ if (resourceType.isEmpty() && resourceId.isEmpty() && resolutionKey.isEmpty()) {
+ throw BluePrintProcessorException(
+ "Can't proceed to get next occurrence: " +
+ "Either provide a resolution-key OR combination of resource-id and resource-type"
+ )
+ }
+
+ if (resolutionKey.isNotEmpty()) {
+ return resourceResolutionDBService.findNextOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+ resolutionKey,
+ blueprintName,
+ blueprintVersion,
+ artifactPrefix
+ )
+ } else {
+ return resourceResolutionDBService.findNextOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
+ blueprintName,
+ blueprintVersion,
+ resourceId,
+ resourceType
+ )
+ }
+ }
}
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt
index b5d4e4515..1f0171f9f 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt
@@ -229,4 +229,52 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
throw BluePrintException("Failed to batch delete resource resolution", ex)
}
}
+
+ /**
+ * This method returns the (highest occurrence + 1) of resource resolutions if present in DB, returns 1 otherwise.
+ * The 'occurrence' is used to persist new resource resolution in the DB.
+ *
+ * @param resolutionKey
+ * @param blueprintName
+ * @param blueprintVersion
+ * @param artifactPrefix
+ */
+ suspend fun findNextOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+ resolutionKey: String,
+ blueprintName: String,
+ blueprintVersion: String,
+ artifactPrefix: String
+ ) = withContext(Dispatchers.IO) {
+ val maxOccurrence = resourceResolutionRepository.findMaxOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+ resolutionKey,
+ blueprintName,
+ blueprintVersion,
+ artifactPrefix
+ )
+ maxOccurrence?.inc() ?: 1
+ }
+
+ /**
+ * This method returns the (highest occurrence + 1) of resource resolutions if present in DB, returns 1 otherwise.
+ * The 'occurrence' is used to persist new resource resolution in the DB.
+ *
+ * @param blueprintName
+ * @param blueprintVersion
+ * @param resourceId
+ * @param resourceType
+ */
+ suspend fun findNextOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
+ blueprintName: String,
+ blueprintVersion: String,
+ resourceId: String,
+ resourceType: String
+ ) = withContext(Dispatchers.IO) {
+ val maxOccurrence = resourceResolutionRepository.findMaxOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
+ blueprintName,
+ blueprintVersion,
+ resourceId,
+ resourceType
+ )
+ maxOccurrence?.inc() ?: 1
+ }
}
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt
index 6e0ed3a4b..8513bda88 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt
@@ -36,6 +36,28 @@ interface ResourceResolutionRepository : JpaRepository<ResourceResolution, Strin
@Param("name")name: String
): ResourceResolution?
+ @Query(
+ value = "SELECT max(occurrence) FROM RESOURCE_RESOLUTION WHERE resolution_key = :key AND blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion AND artifact_name = :artifactName ",
+ nativeQuery = true
+ )
+ fun findMaxOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+ @Param("key")key: String,
+ @Param("blueprintName")blueprintName: String,
+ @Param("blueprintVersion")blueprintVersion: String,
+ @Param("artifactName")artifactName: String
+ ): Int?
+
+ @Query(
+ value = "SELECT max(occurrence) FROM RESOURCE_RESOLUTION WHERE blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion AND resource_id = :resourceId AND resource_type = :resourceType ",
+ nativeQuery = true
+ )
+ fun findMaxOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
+ @Param("blueprintName")blueprintName: String,
+ @Param("blueprintVersion")blueprintVersion: String,
+ @Param("resourceId")resourceId: String,
+ @Param("resourceType")resourceType: String
+ ): Int?
+
fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
resolutionKey: String,
blueprintName: String,
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt
index 3d2a9755c..a801a7eb9 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt
@@ -153,6 +153,195 @@ class ResourceResolutionServiceTest {
}
}
+ /**
+ * Always perform new resolution even if resolution exists in the database.
+ */
+ @Test
+ @Throws(Exception::class)
+ fun testResolveResourceAlwaysPerformNewResolution() {
+ runBlocking {
+ // Occurrence <= 0 indicates to perform new resolution even if resolution exists in the database.
+ props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = -1
+ Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
+
+ val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(
+ "1234",
+ "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration"
+ )
+
+ // Request#1
+ val executionServiceInput =
+ JacksonUtils.readValueFromClassPathFile(
+ "payload/requests/sample-resourceresolution-request.json",
+ ExecutionServiceInput::class.java
+ )!!
+
+ val resourceAssignmentRuntimeService =
+ ResourceAssignmentUtils.transformToRARuntimeService(
+ bluePrintRuntimeService,
+ "testResolveResource"
+ )
+
+ // Prepare inputs from Request#1
+ PayloadUtils.prepareInputsFromWorkflowPayload(
+ bluePrintRuntimeService,
+ executionServiceInput.payload,
+ "resource-assignment"
+ )
+
+ // Resolve resources as per Request#1
+ resourceResolutionService.resolveResources(
+ resourceAssignmentRuntimeService,
+ "resource-assignment",
+ "baseconfig",
+ props
+ )
+
+ // Request#2
+ val executionServiceInput2 =
+ JacksonUtils.readValueFromClassPathFile(
+ "payload/requests/sample-resourceresolution-request2.json",
+ ExecutionServiceInput::class.java
+ )!!
+
+ // Prepare inputs from Request#2
+ PayloadUtils.prepareInputsFromWorkflowPayload(
+ bluePrintRuntimeService,
+ executionServiceInput2.payload,
+ "resource-assignment"
+ )
+
+ // Resolve resources as per Request#2
+ resourceResolutionService.resolveResources(
+ resourceAssignmentRuntimeService,
+ "resource-assignment",
+ "baseconfig",
+ props
+ )
+ }.let { (templateMap, assignmentList) ->
+ assertEquals("This is Sample Velocity Template", templateMap)
+
+ val assignmentListForRequest1 = mutableListOf(
+ "service-instance-id" to "siid_1234",
+ "vnf-id" to "vnf_1234",
+ "vnf_name" to "temp_vnf"
+ )
+ val assignmentListForRequest2 = mutableListOf(
+ "service-instance-id" to "siid_new_resolution",
+ "vnf-id" to "vnf_new_resolution",
+ "vnf_name" to "temp_vnf_new_resolution"
+ )
+ assertEquals(assignmentListForRequest1.size, assignmentList.size)
+ assertEquals(assignmentListForRequest2.size, assignmentList.size)
+
+ // AlwaysPerformNewResolution use case - resolution request #2 should returns the resolution as per
+ // assignmentListForRequest2 since new resolution is performed.
+ var areEqual = assignmentListForRequest1.zip(assignmentList).all { (it1, it2) ->
+ it1.first == it2.name && it1.second == it2.property?.value?.asText() ?: null
+ }
+ assertEquals(false, areEqual)
+
+ areEqual = assignmentListForRequest2.zip(assignmentList).all { (it1, it2) ->
+ it1.first == it2.name && it1.second == it2.property?.value?.asText() ?: null
+ }
+ assertEquals(true, areEqual)
+ }
+ }
+
+ /**
+ * Don't perform new resolution in case resolution already exists in the database.
+ */
+ @Test
+ @Throws(Exception::class)
+ fun testResolveResourceNoNewResolution() {
+ runBlocking {
+ // Occurrence > 0 indicates to not perform new resolution if resolution exists in the database.
+ props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = 1
+ Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
+
+ val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(
+ "1234",
+ "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration"
+ )
+
+ // Request#1
+ val executionServiceInput =
+ JacksonUtils.readValueFromClassPathFile(
+ "payload/requests/sample-resourceresolution-request.json",
+ ExecutionServiceInput::class.java
+ )!!
+
+ val resourceAssignmentRuntimeService =
+ ResourceAssignmentUtils.transformToRARuntimeService(
+ bluePrintRuntimeService,
+ "testResolveResource"
+ )
+
+ // Prepare inputs from Request#1
+ PayloadUtils.prepareInputsFromWorkflowPayload(
+ bluePrintRuntimeService,
+ executionServiceInput.payload,
+ "resource-assignment"
+ )
+ // Resolve resources as per Request#1
+ resourceResolutionService.resolveResources(
+ resourceAssignmentRuntimeService,
+ "resource-assignment",
+ "baseconfig",
+ props
+ )
+
+ // Request#2
+ val executionServiceInput2 =
+ JacksonUtils.readValueFromClassPathFile(
+ "payload/requests/sample-resourceresolution-request2.json",
+ ExecutionServiceInput::class.java
+ )!!
+
+ // Prepare inputs from Request#2
+ PayloadUtils.prepareInputsFromWorkflowPayload(
+ bluePrintRuntimeService,
+ executionServiceInput2.payload,
+ "resource-assignment"
+ )
+
+ // Resolve resources as per Request#2
+ resourceResolutionService.resolveResources(
+ resourceAssignmentRuntimeService,
+ "resource-assignment",
+ "baseconfig",
+ props
+ )
+ }.let { (templateMap, assignmentList) ->
+ assertEquals("This is Sample Velocity Template", templateMap)
+
+ val assignmentListForRequest1 = mutableListOf(
+ "service-instance-id" to "siid_1234",
+ "vnf-id" to "vnf_1234",
+ "vnf_name" to "temp_vnf"
+ )
+ val assignmentListForRequest2 = mutableListOf(
+ "service-instance-id" to "siid_new_resolution",
+ "vnf-id" to "vnf_new_resolution",
+ "vnf_name" to "temp_vnf_new_resolution"
+ )
+ assertEquals(assignmentListForRequest1.size, assignmentList.size)
+ assertEquals(assignmentListForRequest2.size, assignmentList.size)
+
+ // NoNewResolution use case - resolution for request #2 returns the same resolution as
+ // assignmentListForRequest1 since no new resolution is/was actually performed.
+ var areEqual = assignmentListForRequest1.zip(assignmentList).all { (it1, it2) ->
+ it1.first == it2.name && it1.second == it2.property?.value?.asText() ?: null
+ }
+ assertEquals(true, areEqual)
+
+ areEqual = assignmentListForRequest2.zip(assignmentList).all { (it1, it2) ->
+ it1.first == it2.name && it1.second == it2.property?.value?.asText() ?: null
+ }
+ assertEquals(false, areEqual)
+ }
+ }
+
@Test
@Throws(Exception::class)
fun testResolveResources() {
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/resources/payload/requests/sample-resourceresolution-request2.json b/ms/blueprintsprocessor/functions/resource-resolution/src/test/resources/payload/requests/sample-resourceresolution-request2.json
new file mode 100644
index 000000000..726477515
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/resources/payload/requests/sample-resourceresolution-request2.json
@@ -0,0 +1,31 @@
+{
+ "actionIdentifiers": {
+ "actionName": "sample-action",
+ "blueprintName": "sample-blueprint",
+ "blueprintVersion": "1.0.0",
+ "mode": "sync"
+ },
+ "commonHeader": {
+ "flags": {
+ "isForce": true,
+ "ttl": 3600
+ },
+ "originatorId": "unit_tests",
+ "requestId": "123456-1001",
+ "subRequestId": "sub-123456-1001"
+ },
+ "payload": {
+ "resource-assignment-request": {
+ "resource-assignment-properties": {
+ "request-id": "1234",
+ "profile_name": "1.0.0",
+ "service-instance-id": "siid_new_resolution",
+ "vnf-id": "vnf_new_resolution",
+ "action-name": "assign-activate",
+ "scope-type": "vnf-type",
+ "hostname": "localhost",
+ "vnf_name": "temp_vnf_new_resolution"
+ }
+ }
+ }
+}