val artifactMapping = "$artifactPrefix-mapping"
val forceResolution = isForceResolution(properties)
+ val propertiesMutableMap = properties.toMutableMap()
log.info("Resolving resource with resource assignment artifact($artifactMapping)")
val resourceAssignmentContent =
?: 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)
resourceDefinitions,
resourceAssignments,
artifactPrefix,
- properties
+ propertiesMutableMap
)
val resolutionSummary = properties.getOrDefault(
}
if (isToStore(properties)) {
- templateResolutionDBService.write(properties, resolvedContent, bluePrintRuntimeService, artifactPrefix)
+ templateResolutionDBService.write(propertiesMutableMap, resolvedContent, bluePrintRuntimeService, artifactPrefix)
log.info("Template resolution saved into database successfully : ($properties)")
}
}
}
- // 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 &&
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
+ )
+ }
+ }
}
}
}
+ /**
+ * 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() {