vfModule upgrade: don't fallback on mismatching newest model
[vid.git] / vid-app-common / src / main / java / org / onap / vid / job / command / VfmoduleCommand.kt
index 25373d4..bee42fb 100644 (file)
@@ -1,6 +1,7 @@
 package org.onap.vid.job.command
 
 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate
+import org.onap.vid.exceptions.GenericUncheckedException
 import org.onap.vid.job.Job
 import org.onap.vid.job.JobAdapter
 import org.onap.vid.job.JobCommand
@@ -42,8 +43,8 @@ class VfmoduleCommand @Autowired constructor(
     }
 
     override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan {
-        val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID)
-        val serviceModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO)
+        val serviceInstanceId = serviceInstanceIdFromRequest()
+        val serviceModelInfo = serviceModelInfoFromRequest()
         val vnfModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO)
         val vnfInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID)
         val vgInstaceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VG_INSTANCE_ID)
@@ -61,7 +62,7 @@ class VfmoduleCommand @Autowired constructor(
     }
 
     override fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan {
-        val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID)
+        val serviceInstanceId = serviceInstanceIdFromRequest()
         val vnfInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID)
 
         val path = asyncInstantiationBL.getVfModuleDeletePath(serviceInstanceId, vnfInstanceId, getRequest().instanceId)
@@ -82,7 +83,7 @@ class VfmoduleCommand @Autowired constructor(
 
         val newestModel = fetchNewestServiceModel()
 
-        val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID)
+        val serviceInstanceId = serviceInstanceIdFromRequest()
         val vnfInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID)
 
         val (serviceModelInfo, vnfModelInfo, vfmModelInfo) = newestSelector(newestModel, commandParentData);
@@ -103,44 +104,52 @@ class VfmoduleCommand @Autowired constructor(
     data class ModelsInfoTriplet(val serviceModelInfo: ModelInfo, val vnfModelInfo: ModelInfo, val vfmModelInfo: ModelInfo)
 
     private fun newestSelector(newestModel: ServiceModel, commandParentData: CommandParentData): ModelsInfoTriplet {
-        val serviceModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO)
-        val vfmModelInfo = getRequest().modelInfo
-        val vnfModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO)
-
-        val newestServiceModelInfo = newestServiceModelInfo(newestModel)
-        val newestVfmModelInfo = newestVfmModelInfo(newestModel)
-        val newestVnfModelInfo = newestVnfModelInfo(newestModel, commandParentData)
-
-        return if (newestServiceModelInfo == null || newestVfmModelInfo == null || newestVnfModelInfo == null) {
-            ModelsInfoTriplet(serviceModelInfo, vnfModelInfo, vfmModelInfo)
-        } else {
-            ModelsInfoTriplet(newestServiceModelInfo, newestVnfModelInfo, newestVfmModelInfo)
+        try {
+            return ModelsInfoTriplet(
+                    newestServiceModelInfo(newestModel),
+                    newestVnfModelInfo(newestModel, commandParentData),
+                    newestVfmModelInfo(newestModel)
+            )
+        } catch (e: Exception) {
+            throw GenericUncheckedException("Cannot upgrade ${serviceModelInfoFromRequest()} to ${newestModel.service}", e)
         }
     }
 
     private fun newestServiceModelInfo(newestModel: ServiceModel) = toModelInfo(newestModel.service)
 
-    private fun newestVfmModelInfo(newestModel: ServiceModel): ModelInfo? {
+    private fun newestVfmModelInfo(newestModel: ServiceModel): ModelInfo {
         val vfmModelInfo = getRequest().modelInfo
-        val matchingVfms = selectVfms(newestModel, vfmModelInfo)
-        return toModelInfo(matchingVfms.getOrNull(0))
+        val matchingVfm = selectVfm(newestModel, vfmModelInfo)
+        return toModelInfo(matchingVfm)
     }
 
-    private fun newestVnfModelInfo(newestModel: ServiceModel, commandParentData: CommandParentData): ModelInfo? {
+    private fun newestVnfModelInfo(newestModel: ServiceModel, commandParentData: CommandParentData): ModelInfo {
         val vnfModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO)
-        val matchingVnfs = selectVnfs(newestModel, vnfModelInfo)
-        return toModelInfo(matchingVnfs.getOrNull(0))
+        val matchingVnf = selectVnf(newestModel, vnfModelInfo)
+        return toModelInfo(matchingVnf)
     }
 
-    private fun selectVfms(newestModel: ServiceModel, modelInfo: ModelInfo) =
-            newestModel.vfModules.values.filter { it.modelCustomizationName == modelInfo.modelCustomizationName }
-
-    private fun selectVnfs(newestModel: ServiceModel, modelInfo: ModelInfo) =
-            newestModel.vnfs.values.filter { it.modelCustomizationName == modelInfo.modelCustomizationName }
+    internal fun selectVfm(serviceModel: ServiceModel, modelInfo: ModelInfo): ToscaVfm =
+            exactlyOne("vfModule for modelCustomizationName \"${modelInfo.modelCustomizationName}\"") {
+                serviceModel.vfModules.values.single { it.modelCustomizationName == modelInfo.modelCustomizationName }
+            }
+
+    internal fun selectVnf(serviceModel: ServiceModel, modelInfo: ModelInfo): VNF =
+            exactlyOne("VNF for modelCustomizationName \"${modelInfo.modelCustomizationName}\"") {
+                serviceModel.vnfs.values.single { it.modelCustomizationName == modelInfo.modelCustomizationName }
+            }
+
+    private fun <T: Any> exactlyOne(predicateDescription: String, itemSupplier: () -> T): T {
+        return try {
+            itemSupplier.invoke()
+        } catch (cause: Exception) {
+            throw IllegalStateException("Cannot match ${predicateDescription}: ${cause.localizedMessage}", cause)
+        }
+    }
 
-    private fun toModelInfo(toBeConverted: VNF?): ModelInfo? = toBeConverted?.let { toModelInfo(it, "vnf") }
+    private fun toModelInfo(toBeConverted: VNF): ModelInfo = toModelInfo(toBeConverted, "vnf")
 
-    private fun toModelInfo(toBeConverted: ToscaVfm?): ModelInfo? = toBeConverted?.let { toModelInfo(it, "vfModule") }
+    private fun toModelInfo(toBeConverted: ToscaVfm): ModelInfo = toModelInfo(toBeConverted, "vfModule")
 
     private fun toModelInfo(toBeConverted: MinimalNode, modelType: String): ModelInfo {
         val targetModelInfo = ModelInfo()
@@ -167,11 +176,7 @@ class VfmoduleCommand @Autowired constructor(
         return targetModelInfo
     }
 
-    private fun toModelInfo(toBeConverted: Service?): ModelInfo? {
-
-        if (toBeConverted == null)
-            return null
-
+    internal fun toModelInfo(toBeConverted: Service): ModelInfo {
         val targetModelInfo = ModelInfo()
 
         targetModelInfo.modelVersionId = toBeConverted.uuid
@@ -197,10 +202,15 @@ class VfmoduleCommand @Autowired constructor(
         return getActionType() == Action.Upgrade
     }
 
+    @Throws(IllegalStateException::class)
     private fun fetchNewestServiceModel(): ServiceModel {
-        val serviceModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO)
-        var modelNewestUuid = commandUtils.getNewestModelUuid(serviceModelInfo.modelInvariantId);
-        var serviceNewestModel = commandUtils.getServiceModel(modelNewestUuid);
+        val serviceModelInfo = serviceModelInfoFromRequest()
+        val modelNewestUuid = commandUtils.getNewestModelUuid(serviceModelInfo.modelInvariantId);
+
+        check(!modelNewestUuid.equals(serviceModelInfo.modelVersionId, true)) {
+            "Model version id ${serviceModelInfo.modelVersionId} is already the latest version of model's invariant id ${serviceModelInfo.modelInvariantId}" }
+
+        val serviceNewestModel = commandUtils.getServiceModel(modelNewestUuid);
 
         return serviceNewestModel;
     }