Don't use EELFLoggerDelegate.errorLogger in Async jobs
[vid.git] / vid-app-common / src / main / java / org / onap / vid / job / command / VnfCommand.kt
1 package org.onap.vid.job.command
2
3 import org.apache.commons.collections.MapUtils
4 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate
5 import org.onap.vid.asdc.AsdcCatalogException
6 import org.onap.vid.job.*
7 import org.onap.vid.job.impl.JobSharedData
8 import org.onap.vid.model.Action
9 import org.onap.vid.model.serviceInstantiation.BaseResource
10 import org.onap.vid.model.serviceInstantiation.VfModule
11 import org.onap.vid.model.serviceInstantiation.Vnf
12 import org.onap.vid.mso.RestMsoImplementation
13 import org.onap.vid.properties.Features
14 import org.onap.vid.services.AsyncInstantiationBusinessLogic
15 import org.springframework.beans.factory.annotation.Autowired
16 import org.springframework.beans.factory.config.ConfigurableBeanFactory
17 import org.springframework.context.annotation.Scope
18 import org.springframework.http.HttpMethod
19 import org.springframework.stereotype.Component
20 import org.togglz.core.manager.FeatureManager
21 import java.util.*
22 import java.util.stream.Collectors
23 import kotlin.properties.Delegates
24
25 const val NEED_TO_CREATE_BASE_MODULE = "needToCreateBaseModule"
26
27 @Component
28 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
29 class VnfCommand @Autowired constructor(
30         private val asyncInstantiationBL: AsyncInstantiationBusinessLogic,
31         restMso: RestMsoImplementation,
32         private val msoRequestBuilder: MsoRequestBuilder,
33         msoResultHandlerService: MsoResultHandlerService,
34         inProgressStatusService:InProgressStatusService,
35         watchChildrenJobsBL: WatchChildrenJobsBL,
36         jobsBrokerService: JobsBrokerService,
37         jobAdapter: JobAdapter,
38         private val featureManager: FeatureManager
39 ) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService,
40         watchChildrenJobsBL, jobsBrokerService, jobAdapter), JobCommand {
41
42     private var needToCreateBaseModule:Boolean by Delegates.notNull<Boolean>()
43
44     override fun getData(): Map<String, Any?> {
45         return super.getData() + mapOf(NEED_TO_CREATE_BASE_MODULE to needToCreateBaseModule)
46     }
47
48     override fun init(sharedData: JobSharedData, commandData: Map<String, Any>): ResourceCommand {
49         super<ResourceCommand>.init(sharedData, commandData)
50         needToCreateBaseModule = commandData.getOrDefault(NEED_TO_CREATE_BASE_MODULE, actionPhase != Action.Delete) as Boolean
51         return this
52     }
53
54
55     override fun createChildren(): Job.JobStatus {
56         val request:Vnf = getRequest()
57         if(isNeedToCreateChildJobs()){
58             val dataForChild = buildDataForChild(request, actionPhase)
59             val vfModules:List<VfModule> = request.vfModules.values.stream().flatMap { vfKey -> vfKey.values.stream() }.collect(Collectors.toList<VfModule>())
60
61             try {
62                 childJobs = pushChildrenJobsToBroker(vfModulesForChildrenJobs(vfModules), dataForChild, JobType.VolumeGroupInstantiation)
63             } catch (e: AsdcCatalogException) {
64                 LOGGER.error("Failed to retrieve service definitions from SDC, for VfModule is BaseModule.. Error: " + e.message, e)
65                 throw e;
66             }
67         }
68
69         return Job.JobStatus.COMPLETED_WITH_NO_ACTION
70     }
71
72     private fun vfModulesForChildrenJobs(vfModules: List<VfModule>): List<VfModule> =
73             vfModules
74                     .filter { filterModuleByNeedToCreateBase(it) }
75                     .map { childVfModuleWithVnfRegionAndTenant(it) }
76
77     internal fun childVfModuleWithVnfRegionAndTenant(vfModule: VfModule): VfModule {
78         if (!shouldEntailRegionAndTenantToVfModule(vfModule)) {
79             return vfModule
80         }
81
82         val vnfLcpCloudRegionId = getRequest().lcpCloudRegionId
83         val vnfTenantId = getRequest().tenantId
84         return vfModule.cloneWith(vnfLcpCloudRegionId, vnfTenantId)
85     }
86
87     private fun shouldEntailRegionAndTenantToVfModule(vfModule: VfModule) =
88             vfModule.action == Action.Create
89                     && featureManager.isActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)
90
91     private fun filterModuleByNeedToCreateBase(vfModule: VfModule): Boolean {
92         return needToCreateBaseModule ==
93                 commandUtils.isVfModuleBaseModule(
94                         serviceModelInfoFromRequest().modelVersionId, vfModule.modelInfo)
95     }
96
97     override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan {
98         val serviceInstanceId = serviceInstanceIdFromRequest()
99
100         val instantiatePath = asyncInstantiationBL.getVnfInstantiationPath(serviceInstanceId)
101
102         val requestDetailsWrapper = msoRequestBuilder.generateVnfInstantiationRequest(
103                 request as Vnf,
104                 serviceModelInfoFromRequest(), serviceInstanceId,
105                 userId,
106                 testApi
107         )
108
109         val actionDescription = "create vnf in $serviceInstanceId"
110
111         return MsoRestCallPlan(HttpMethod.POST, instantiatePath, Optional.of(requestDetailsWrapper), Optional.empty(), actionDescription)
112
113     }
114
115     override fun addMyselfToChildrenData(commandParentData: CommandParentData, request: BaseResource) {
116         commandParentData.addModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO, request.modelInfo);
117         commandParentData.addInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID, getActualInstanceId(request))
118     }
119
120     override fun getRequest(): Vnf {
121         return sharedData.request as Vnf
122     }
123
124     private fun isNeedToCreateChildJobs(): Boolean {
125         return featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE) &&
126                 MapUtils.isNotEmpty(getRequest().vfModules)
127     }
128
129     override fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan {
130         val serviceInstanceId = serviceInstanceIdFromRequest()
131         val path = asyncInstantiationBL.getVnfDeletionPath(serviceInstanceId, getRequest().instanceId)
132         val requestDetailsWrapper = msoRequestBuilder.generateDeleteVnfRequest(getRequest(), userId)
133         return MsoRestCallPlan(HttpMethod.DELETE, path, Optional.of(requestDetailsWrapper), Optional.of(userId),
134                 "delete vnf ${getRequest().instanceId} from service $serviceInstanceId")
135
136     }
137
138     companion object {
139         private val LOGGER = EELFLoggerDelegate.getLogger(VnfCommand::class.java)
140     }
141
142     //in Delete phase - we delete all non-base vf-modules first, before base vf-module
143     //in Create phase - we create base vf-module first, and then all the others
144     override fun watchChildren(): Job.JobStatus {
145         val childrenStatus:Job.JobStatus = comulateStatusAndUpdatePropertyIfFinal(watchChildrenJobsBL.retrieveChildrenJobsStatus(childJobs))
146         if (!childrenStatus.isFinal ||
147                 childrenStatus.isFailure ||
148                 (actionPhase == Action.Create && !needToCreateBaseModule) ||
149                 (actionPhase == Action.Delete && needToCreateBaseModule)) {
150             return childrenStatus
151         }
152
153         needToCreateBaseModule = !needToCreateBaseModule;
154         createChildren()
155         return Job.JobStatus.IN_PROGRESS
156     }
157 }