Don't use EELFLoggerDelegate.errorLogger in Async jobs
[vid.git] / vid-app-common / src / main / java / org / onap / vid / job / command / VfmoduleCommand.kt
index af52fa0..29d7001 100644 (file)
@@ -1,13 +1,15 @@
 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
 import org.onap.vid.job.JobsBrokerService
-import org.onap.vid.model.Action
+import org.onap.vid.model.*
 import org.onap.vid.model.serviceInstantiation.VfModule
 import org.onap.vid.mso.RestMsoImplementation
+import org.onap.vid.mso.model.ModelInfo
 import org.onap.vid.services.AsyncInstantiationBusinessLogic
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.beans.factory.config.ConfigurableBeanFactory
@@ -16,6 +18,8 @@ import org.springframework.http.HttpMethod
 import org.springframework.stereotype.Component
 import java.util.*
 
+typealias ToscaVfm = org.onap.vid.model.VfModule
+
 @Component
 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 class VfmoduleCommand @Autowired constructor(
@@ -39,13 +43,13 @@ 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)
 
-        val instantiatePath = asyncInstantiationBL.getVfmoduleInstantiationPath(serviceInstanceId, vnfInstanceId)
+         val instantiatePath = asyncInstantiationBL.getVfmoduleInstantiationPath(serviceInstanceId, vnfInstanceId)
 
         val requestDetailsWrapper = msoRequestBuilder.generateVfModuleInstantiationRequest(
                 request as VfModule,
@@ -58,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)
@@ -75,24 +79,118 @@ class VfmoduleCommand @Autowired constructor(
         return false
     }
 
-    private fun planReplaceMyselfRestCall(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 vnfModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO)
+    private fun planReplaceMyselfRestCall(commandParentData: CommandParentData): MsoRestCallPlan {
+
+        val newestModel = fetchNewestServiceModel()
+
+        val serviceInstanceId = serviceInstanceIdFromRequest()
         val vnfInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID)
+
+        val (serviceModelInfo, vnfModelInfo, vfmModelInfo) = newestSelector(newestModel, commandParentData);
+
+        val originalRequestWithNewestVfmModelInfo = getRequest().cloneWith(vfmModelInfo)
+
+        val requestDetailsWrapper = msoRequestBuilder.generateVfModuleReplaceRequest(
+                originalRequestWithNewestVfmModelInfo, serviceModelInfo, serviceInstanceId,
+                vnfModelInfo, vnfInstanceId, null, sharedData.userId, sharedData.testApi)
+
+
         val replacePath = asyncInstantiationBL.getVfModuleReplacePath(serviceInstanceId, vnfInstanceId, getRequest().instanceId)
 
-        val requestDetailsWrapper = msoRequestBuilder.generateVfModuleInstantiationRequest( 
-                request as VfModule, serviceModelInfo, serviceInstanceId,vnfModelInfo, vnfInstanceId,null,userId, testApi)
+        return MsoRestCallPlan(HttpMethod.POST, replacePath, Optional.of(requestDetailsWrapper), Optional.of(sharedData.userId),
+                "replace vfmodule ${getRequest().instanceId}")
+    }
+
+    data class ModelsInfoTriplet(val serviceModelInfo: ModelInfo, val vnfModelInfo: ModelInfo, val vfmModelInfo: ModelInfo)
+
+    private fun newestSelector(newestModel: ServiceModel, commandParentData: CommandParentData): ModelsInfoTriplet {
+        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)
 
-        val actionDescription = "replace vfmodule ${request.instanceId}"
+    private fun newestVfmModelInfo(newestModel: ServiceModel): ModelInfo {
+        val vfmModelInfo = getRequest().modelInfo
+        val matchingVfm = selectVfm(newestModel, vfmModelInfo)
+        return toModelInfo(matchingVfm)
+    }
 
-        return MsoRestCallPlan(HttpMethod.POST, replacePath, Optional.of(requestDetailsWrapper), Optional.of(userId), actionDescription)
+    private fun newestVnfModelInfo(newestModel: ServiceModel, commandParentData: CommandParentData): ModelInfo {
+        val vnfModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO)
+        val matchingVnf = selectVnf(newestModel, vnfModelInfo)
+        return toModelInfo(matchingVnf)
+    }
+
+    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 = toModelInfo(toBeConverted, "vnf")
+
+    private fun toModelInfo(toBeConverted: ToscaVfm): ModelInfo = toModelInfo(toBeConverted, "vfModule")
+
+    private fun toModelInfo(toBeConverted: MinimalNode, modelType: String): ModelInfo {
+        val targetModelInfo = ModelInfo()
+
+        targetModelInfo.modelType = modelType
+        targetModelInfo.modelName = toBeConverted.name
+        targetModelInfo.modelNameVersionId = null
+        targetModelInfo.modelVersion = toBeConverted.version
+        targetModelInfo.modelVersionId = toBeConverted.uuid
+        targetModelInfo.modelInvariantId = toBeConverted.invariantUuid
+
+        targetModelInfo.modelCustomizationId = when (toBeConverted) {
+            is VNF -> toBeConverted.customizationUuid
+            is ToscaVfm -> toBeConverted.customizationUuid
+            else -> throw IllegalArgumentException()
+        }
+
+        targetModelInfo.modelCustomizationName = when (toBeConverted) {
+            is VNF -> toBeConverted.modelCustomizationName
+            is ToscaVfm -> toBeConverted.modelCustomizationName
+            else -> throw IllegalArgumentException()
+        }
+
+        return targetModelInfo
+    }
+
+    internal fun toModelInfo(toBeConverted: Service): ModelInfo {
+        val targetModelInfo = ModelInfo()
+
+        targetModelInfo.modelVersionId = toBeConverted.uuid
+        targetModelInfo.modelInvariantId = toBeConverted.invariantUuid
+        targetModelInfo.modelVersion = toBeConverted.version
+        targetModelInfo.modelType = "service"
+        targetModelInfo.modelName = toBeConverted.name
+
+        return targetModelInfo
     }
 
     override fun replaceMyself(): Job.JobStatus {
         try {
-            val replaceMyselfCommand = planReplaceMyselfRestCall(commandParentData, sharedData.request, sharedData.userId, sharedData.testApi )
+            val replaceMyselfCommand = planReplaceMyselfRestCall(commandParentData)
             return executeAndHandleMsoInstanceRequest(replaceMyselfCommand)
         } catch (exception: Exception) {
             LOGGER.error("Failed to replace instanceId ${getRequest().instanceId} ", exception)
@@ -101,6 +199,16 @@ class VfmoduleCommand @Autowired constructor(
     }
 
     override fun isNeedToReplaceMySelf(): Boolean {
-        return getActionType() == Action.Replace
+        return getActionType() == Action.Upgrade
+    }
+
+    @Throws(IllegalStateException::class)
+    private fun fetchNewestServiceModel(): ServiceModel {
+        val serviceModelInfo = serviceModelInfoFromRequest()
+        val modelNewestUuid = commandUtils.getNewestModelUuid(serviceModelInfo.modelInvariantId);
+
+        val serviceNewestModel = commandUtils.getServiceModel(modelNewestUuid);
+
+        return serviceNewestModel;
     }
 }