Merge "Replace vfmodule: expect optional retainVolumeGroups param"
[vid.git] / vid-app-common / src / main / java / org / onap / vid / job / command / MsoRequestBuilder.kt
1 package org.onap.vid.job.command
2
3 import com.google.common.collect.ImmutableList
4 import org.apache.commons.lang3.ObjectUtils.defaultIfNull
5 import org.apache.commons.lang3.StringUtils
6 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate
7 import org.onap.vid.aai.AaiClientInterface
8 import org.onap.vid.aai.ExceptionWithRequestInfo
9 import org.onap.vid.aai.model.ResourceType
10 import org.onap.vid.changeManagement.RequestDetailsWrapper
11 import org.onap.vid.model.serviceInstantiation.*
12 import org.onap.vid.mso.model.*
13 import org.onap.vid.mso.model.BaseResourceInstantiationRequestDetails.*
14 import org.onap.vid.mso.model.VfModuleInstantiationRequestDetails.UserParamMap
15 import org.onap.vid.mso.rest.SubscriberInfo
16 import org.onap.vid.properties.Features
17 import org.onap.vid.services.AsyncInstantiationBusinessLogic
18 import org.onap.vid.services.CloudOwnerService
19 import org.onap.vid.utils.JACKSON_OBJECT_MAPPER
20 import org.springframework.beans.factory.annotation.Autowired
21 import org.springframework.stereotype.Service
22 import org.togglz.core.manager.FeatureManager
23 import java.util.*
24 import java.util.Collections.emptyList
25 import java.util.stream.Collectors
26
27 @Service
28 class MsoRequestBuilder
29 @Autowired constructor(private val asyncInstantiationBL: AsyncInstantiationBusinessLogic,
30                        private val cloudOwnerService: CloudOwnerService,
31                        private val aaiClient: AaiClientInterface,
32                        private val featureManager: FeatureManager) {
33
34     companion object {
35         private val LOGGER = EELFLoggerDelegate.getLogger(MsoRequestBuilder::class.java)
36         private const val VID_SOURCE = "VID"
37         private const val DISABLED_HOMING_VALUE = "none"
38     }
39
40     fun generateALaCarteServiceInstantiationRequest(payload: ServiceInstantiation, optimisticUniqueServiceInstanceName: String, userId: String): RequestDetailsWrapper<ServiceInstantiationRequestDetails> {
41         val userParams = generateUserParamList()
42
43         val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, true, userParams, payload.testApi)
44
45         val requestDetails = generateServiceInstantiationRequestDetails(payload, requestParameters, optimisticUniqueServiceInstanceName, userId)
46
47         return RequestDetailsWrapper(requestDetails)
48     }
49
50     fun generateServiceDeletionRequest(payload: ServiceInstantiation, userId: String): RequestDetailsWrapper<ServiceDeletionRequestDetails> {
51
52         val requestParameters = ServiceDeletionRequestDetails.RequestParameters(payload.isALaCarte, payload.testApi)
53
54         val requestInfo = ServiceDeletionRequestDetails.RequestInfo(
55                 VID_SOURCE,
56                 userId)
57
58         val requestDetails = ServiceDeletionRequestDetails(payload.modelInfo, requestInfo, requestParameters)
59
60         return RequestDetailsWrapper(requestDetails)
61     }
62
63     fun generateMacroServiceInstantiationRequest(jobId: UUID?, payload: ServiceInstantiation, optimisticUniqueServiceInstanceName: String, userId: String): RequestDetailsWrapper<ServiceInstantiationRequestDetails> {
64         val serviceInstanceName = generateServiceName(jobId, payload, optimisticUniqueServiceInstanceName)
65
66         val serviceInstantiationServiceList = generateMacroServiceInstantiationRequestParams(payload, serviceInstanceName, jobId)
67
68
69         val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, false, serviceInstantiationServiceList)
70
71         val requestDetails = generateServiceInstantiationRequestDetails(payload, requestParameters, serviceInstanceName, userId)
72
73         return RequestDetailsWrapper(requestDetails)
74     }
75
76     fun generateNetworkInstantiationRequest(networkDetails: Network, serviceModelInfo: ModelInfo, serviceInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<NetworkInstantiationRequestDetails> {
77         val requestInfo = generateRequestInfo(networkDetails.instanceName, ResourceType.L3_NETWORK, networkDetails.isRollbackOnFailure, networkDetails.productFamilyId, userId)
78         val cloudConfiguration = generateCloudConfiguration(networkDetails.lcpCloudRegionId, networkDetails.tenantId)
79         val platform = Platform(networkDetails.platformName)
80         val lineOfBusiness = LineOfBusiness.of(networkDetails.lineOfBusiness)
81         val requestParameters = BaseResourceInstantiationRequestDetails.RequestParameters(generateUserParamList(), testApi)
82         val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo))
83         return RequestDetailsWrapper(NetworkInstantiationRequestDetails(networkDetails.modelInfo, cloudConfiguration, requestInfo, platform, lineOfBusiness, relatedInstanceList, requestParameters))
84     }
85
86     fun generateVnfInstantiationRequest(vnfDetails: Vnf, serviceModelInfo: ModelInfo, serviceInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<VnfInstantiationRequestDetails> {
87         val requestInfo = generateRequestInfo(vnfDetails.instanceName, ResourceType.GENERIC_VNF, vnfDetails.isRollbackOnFailure, vnfDetails.productFamilyId, userId)
88         val cloudConfiguration = generateCloudConfiguration(vnfDetails.lcpCloudRegionId, vnfDetails.tenantId)
89         val platform = Platform(vnfDetails.platformName)
90         val lineOfBusiness = LineOfBusiness.of(vnfDetails.lineOfBusiness)
91         val requestParameters = BaseResourceInstantiationRequestDetails.RequestParameters(generateUserParamList(), testApi)
92         val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo))
93         return RequestDetailsWrapper(VnfInstantiationRequestDetails(vnfDetails.modelInfo, cloudConfiguration, requestInfo, platform, lineOfBusiness, relatedInstanceList, requestParameters))
94     }
95
96     fun generateDeleteVnfRequest(vnfDetails: Vnf, userId: String): RequestDetailsWrapper<VnfInstantiationRequestDetails> {
97         val requestInfo = generateRequestInfo(null, null, null, null, userId)
98         val cloudConfiguration = generateCloudConfiguration(vnfDetails.lcpCloudRegionId, vnfDetails.tenantId)
99         return RequestDetailsWrapper(VnfInstantiationRequestDetails(vnfDetails.modelInfo, cloudConfiguration, requestInfo, null, null, null, null))
100     }
101
102     fun generateVfModuleInstantiationRequest(
103             vfModuleDetails: VfModule, serviceModelInfo: ModelInfo,
104             serviceInstanceId: String, vnfModelInfo: ModelInfo, vnfInstanceId: String,
105             vgInstanceId: String?, userId: String, testApi: String?
106     ): RequestDetailsWrapper<VfModuleInstantiationRequestDetails> {
107         val requestInfo = generateRequestInfo(vfModuleDetails.instanceName, ResourceType.VF_MODULE, vfModuleDetails.isRollbackOnFailure, null, userId)
108
109         //cloud configuration
110         val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId)
111
112         //request parameters
113         val userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
114         val requestParameters = VfModuleInstantiationRequestDetails.RequestParametersVfModule(
115                 userParams, vfModuleDetails.isUsePreload, testApi, nullSafeNegate(vfModuleDetails.isRetainVolumeGroups))
116
117         //related instance list
118         val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo, vnfInstanceId to vnfModelInfo))
119         if (StringUtils.isNotEmpty(vgInstanceId)) {
120             val volumeGroupModel = ModelInfo()
121             volumeGroupModel.modelType = "volumeGroup"
122             relatedInstanceList.add(RelatedInstance(volumeGroupModel, vgInstanceId, vfModuleDetails.volumeGroupInstanceName))
123         }
124         return RequestDetailsWrapper(VfModuleInstantiationRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters))
125     }
126
127     private fun nullSafeNegate(booleanValue: Boolean?): Boolean? = booleanValue?.not()
128
129     fun generateVolumeGroupInstantiationRequest(vfModuleDetails: VfModule, serviceModelInfo: ModelInfo, serviceInstanceId: String, vnfModelInfo: ModelInfo, vnfInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<VolumeGroupRequestDetails> {
130         val requestInfo = generateRequestInfo(vfModuleDetails.volumeGroupInstanceName, ResourceType.VOLUME_GROUP, vfModuleDetails.isRollbackOnFailure, null, userId)
131         val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId)
132         val userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
133         val requestParameters = VfModuleInstantiationRequestDetails.RequestParametersVfModule(userParams, vfModuleDetails.isUsePreload, testApi, null)
134         val relatedInstances = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo, vnfInstanceId to vnfModelInfo))
135
136         vfModuleDetails.modelInfo.modelType = "volumeGroup"
137         return RequestDetailsWrapper(VolumeGroupRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstances, requestParameters))
138     }
139
140     fun generateInstanceGroupInstantiationRequest(instanceGroupDetails: InstanceGroup, serviceModelInfo: ModelInfo, serviceInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<InstanceGroupInstantiationRequestDetails> {
141         val requestInfo = generateRequestInfo(instanceGroupDetails.instanceName, ResourceType.INSTANCE_GROUP, instanceGroupDetails.isRollbackOnFailure, null, userId)
142         val requestParameters = BaseResourceInstantiationRequestDetails.RequestParameters(generateUserParamList(), testApi)
143         val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo))
144         return RequestDetailsWrapper(InstanceGroupInstantiationRequestDetails(instanceGroupDetails.modelInfo, requestInfo, relatedInstanceList, requestParameters))
145     }
146
147     fun generateInstanceGroupMemberRequest(instanceGroupMemberId: String, userId: String): RequestDetailsWrapper<AddOrRemoveInstanceGroupMemberRequestDetails> {
148         val requestInfo = generateRequestInfo(null, null, null, null, userId)
149         val modelInfo = ModelInfo()
150         modelInfo.modelType = "vnf"
151         val relatedInstanceList = generateRelatedInstances(mapOf(instanceGroupMemberId to modelInfo))
152         return RequestDetailsWrapper(AddOrRemoveInstanceGroupMemberRequestDetails(requestInfo, relatedInstanceList))
153     }
154
155     fun generateDeleteNetworkRequest(networkDetails: Network, userId: String): RequestDetailsWrapper<NetworkInstantiationRequestDetails> {
156         val requestInfo = generateRequestInfo(null, null, null, null, userId)
157         val cloudConfiguration = generateCloudConfiguration(networkDetails.lcpCloudRegionId, networkDetails.tenantId)
158         return RequestDetailsWrapper(NetworkInstantiationRequestDetails(networkDetails.modelInfo, cloudConfiguration, requestInfo, null, null, null, null))
159     }
160
161     fun generateDeleteVfModuleRequest(vfModuleDetails: VfModule, userId: String): RequestDetailsWrapper<VfModuleInstantiationRequestDetails> {
162         val requestInfo = generateRequestInfo(null, null, null, null, userId)
163         val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId)
164         return RequestDetailsWrapper(VfModuleInstantiationRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, null, null))
165     }
166
167     private fun generateServiceName(jobId: UUID?, payload: ServiceInstantiation, optimisticUniqueServiceInstanceName: String): String? {
168         var serviceInstanceName: String? = null
169         if (StringUtils.isNotEmpty(optimisticUniqueServiceInstanceName)) {
170             serviceInstanceName = peekServiceName(jobId, payload, optimisticUniqueServiceInstanceName)
171         }
172         return serviceInstanceName
173     }
174
175     private fun peekServiceName(jobId: UUID?, payload: ServiceInstantiation, optimisticUniqueServiceInstanceName: String): String {
176         val serviceInstanceName: String
177         // unique name already exist in service info. If it's free in AAI we use it
178         if (isNameFreeInAai(optimisticUniqueServiceInstanceName, ResourceType.SERVICE_INSTANCE)) {
179             serviceInstanceName = optimisticUniqueServiceInstanceName
180         } else {
181             serviceInstanceName = asyncInstantiationBL.getUniqueName(payload.instanceName, ResourceType.SERVICE_INSTANCE)
182         }//otherwise we used the original service instance name (from payload) to get a new unique name from DB and AAI
183
184         //update serviceInfo with new name if needed
185         try {
186             asyncInstantiationBL.updateServiceInfo(jobId) { x -> x.serviceInstanceName = serviceInstanceName }
187         } catch (e: Exception) {
188             LOGGER.error("Failed updating service name {} in serviceInfo", serviceInstanceName, e)
189         }
190
191         return serviceInstanceName
192     }
193
194     @Throws(ExceptionWithRequestInfo::class)
195     private fun isNameFreeInAai(name: String, resourceType: ResourceType): Boolean {
196         return !aaiClient.isNodeTypeExistsByName(name, resourceType)
197     }
198
199     private fun generateServiceInstantiationServicesList(payload: ServiceInstantiation, serviceInstanceName: String?, vnfList: ServiceInstantiationRequestDetails.ServiceInstantiationVnfList): List<ServiceInstantiationRequestDetails.ServiceInstantiationService> {
200         val serviceInstantiationServiceList = LinkedList<ServiceInstantiationRequestDetails.ServiceInstantiationService>()
201         val unFilteredInstanceParams = defaultIfNull<List<MutableMap<String, String>>>(payload.instanceParams, emptyList())
202         val filteredInstanceParams = removeUnNeededParams(unFilteredInstanceParams)
203         val serviceInstantiationService = ServiceInstantiationRequestDetails.ServiceInstantiationService(
204                 payload.modelInfo,
205                 serviceInstanceName,
206                 filteredInstanceParams,
207                 vnfList
208         )
209         serviceInstantiationServiceList.add(serviceInstantiationService)
210         return serviceInstantiationServiceList
211     }
212
213     private fun removeUnNeededParams(instanceParams: List<MutableMap<String, String>>?): List<MutableMap<String, String>> {
214         val keysToRemove = mutableListOf<String>()
215         if (instanceParams.isNullOrEmpty()) {
216             return emptyList()
217         }
218
219         for (key in instanceParams[0].keys) {
220             for (paramToIgnore in AsyncInstantiationBusinessLogic.PARAMS_TO_IGNORE)
221                 if (key.equals(paramToIgnore, ignoreCase = true)) {
222                     keysToRemove.add(key)
223                 }
224         }
225
226         val result: MutableMap<String, String> = instanceParams[0].entries.stream()
227                 .filter { entry -> !keysToRemove.contains(entry.key) }
228                 .collect(Collectors.toMap({ it.key }, { it.value }))
229
230         return if (result.isEmpty()) emptyList() else listOf(result)
231     }
232
233     private fun createServiceInstantiationVnfList(jobId: UUID?, payload: ServiceInstantiation): ServiceInstantiationRequestDetails.ServiceInstantiationVnfList {
234         val cloudConfiguration = generateCloudConfiguration(payload.lcpCloudRegionId, payload.tenantId)
235         val isBulk = asyncInstantiationBL.isPartOfBulk(jobId)
236
237         val vnfs = payload.vnfs
238         val vnfList = mutableListOf<ServiceInstantiationRequestDetails.ServiceInstantiationVnf>()
239         for (vnf in vnfs.values) {
240             val vfModules = vnf.vfModules
241             val convertedUnFilteredVfModules = convertVfModuleMapToList(vfModules)
242             val filteredVfModules = filterInstanceParamsFromVfModuleAndUniqueNames(convertedUnFilteredVfModules, isBulk)
243             val serviceInstantiationVnf = ServiceInstantiationRequestDetails.ServiceInstantiationVnf(
244                     vnf.modelInfo,
245                     cloudConfiguration,
246                     vnf.platformName,
247                     vnf.lineOfBusiness,
248                     payload.productFamilyId,
249                     buildVnfInstanceParams(vnf.instanceParams, filteredVfModules),
250                     filteredVfModules,
251                     getUniqueNameIfNeeded(vnf.instanceName, ResourceType.GENERIC_VNF, isBulk)
252             )
253             vnfList.add(serviceInstantiationVnf)
254         }
255
256         return ServiceInstantiationRequestDetails.ServiceInstantiationVnfList(vnfList)
257     }
258
259     private fun convertVfModuleMapToList(vfModules: Map<String, Map<String, VfModule>>): List<VfModuleMacro> {
260         return vfModules.values.stream().flatMap { vfModule ->
261             vfModule.values.stream().map { item ->
262                 val aggregatedParams = aggregateAllInstanceParams(extractActualInstanceParams(item.instanceParams), item.supplementaryParams)
263                 val aggregatedParamsConverted = JACKSON_OBJECT_MAPPER.convertValue(aggregatedParams, List::class.java)
264
265                 VfModuleMacro(
266                         item.modelInfo,
267                         item.instanceName,
268                         item.volumeGroupInstanceName,
269                         aggregatedParamsConverted as List<Map<String, String>>)
270             }
271         }.collect(Collectors.toList<VfModuleMacro>())
272     }
273
274     fun aggregateAllInstanceParams(instanceParams: Map<String, String>?, supplementaryParams: Map<String, String>?): List<VfModuleInstantiationRequestDetails.UserParamMap<String, String>> {
275         var instanceParamsFinal: Map<String, String> = instanceParams ?: emptyMap()
276         val supplementaryParamsFinal: Map<String, String> = supplementaryParams ?: emptyMap()
277
278         if (!(instanceParamsFinal.isEmpty() && supplementaryParamsFinal.isEmpty())) {
279             //remove duplicate keys from instanceParams if exist in supplementaryParams
280             instanceParamsFinal = instanceParamsFinal.entries.stream()
281                     .filter { m -> !supplementaryParamsFinal.containsKey(m.key) }
282                     .collect(Collectors.toMap({ it.key }, { it.value }))
283
284             //aggregate the 2 collections and format them as UserParamMap
285             val aggregatedParams = UserParamMap<String, String>()
286             aggregatedParams.putAll(instanceParamsFinal)
287             aggregatedParams.putAll(supplementaryParamsFinal)
288
289             return mutableListOf(aggregatedParams)
290         }
291
292         return emptyList()
293     }
294
295     //Make sure we always get a one Map from InstanceParams
296     private fun extractActualInstanceParams(originalInstanceParams: List<MutableMap<String, String>>?): MutableMap<String, String> {
297         return if (originalInstanceParams.isNullOrEmpty() || originalInstanceParams[0].isNullOrEmpty()) {
298             mutableMapOf()
299         } else originalInstanceParams[0]
300     }
301
302     private fun filterInstanceParamsFromVfModuleAndUniqueNames(unFilteredVfModules: List<VfModuleMacro>, isBulk: Boolean): List<VfModuleMacro> {
303         return unFilteredVfModules.stream().map { vfModule ->
304             VfModuleMacro(
305                     vfModule.modelInfo,
306                     getUniqueNameIfNeeded(vfModule.instanceName, ResourceType.VF_MODULE, isBulk),
307                     getUniqueNameIfNeeded(vfModule.volumeGroupInstanceName, ResourceType.VOLUME_GROUP, isBulk),
308                     removeUnNeededParams(vfModule.instanceParams))
309         }
310                 .collect(Collectors.toList<VfModuleMacro>())
311     }
312
313     fun buildVnfInstanceParams(currentVnfInstanceParams: List<MutableMap<String, String>>, vfModules: List<VfModuleMacro>): List<Map<String, String>> {
314         val filteredVnfInstanceParams = removeUnNeededParams(currentVnfInstanceParams)
315
316         val vnfInstanceParams = extractActualInstanceParams(filteredVnfInstanceParams)
317         vfModules.stream()
318                 .map { x -> extractActualInstanceParams(x.instanceParams) }
319                 .forEach { vnfInstanceParams.putAll(it) }
320         return if (vnfInstanceParams.isEmpty()) emptyList() else ImmutableList.of(vnfInstanceParams)
321     }
322
323     private fun generateServiceInstantiationRequestDetails(payload: ServiceInstantiation, requestParameters: ServiceInstantiationRequestDetails.RequestParameters, serviceInstanceName: String?, userId: String): ServiceInstantiationRequestDetails {
324         val requestInfo = ServiceInstantiationRequestDetails.RequestInfo(serviceInstanceName,
325                 payload.productFamilyId,
326                 VID_SOURCE,
327                 payload.isRollbackOnFailure,
328                 userId)
329         val owningEntity = ServiceInstantiationRequestDetails.ServiceInstantiationOwningEntity(payload.owningEntityId, payload.owningEntityName)
330         val subscriberInfo = generateSubscriberInfo(payload)
331         val project = if (payload.projectName != null) ServiceInstantiationRequestDetails.Project(payload.projectName) else null
332         return ServiceInstantiationRequestDetails(payload.modelInfo, owningEntity, subscriberInfo, project, requestInfo, requestParameters)
333     }
334
335     private fun generateSubscriberInfo(payload: ServiceInstantiation): SubscriberInfo {
336         val subscriberInfo = SubscriberInfo()
337         subscriberInfo.globalSubscriberId = payload.globalSubscriberId
338         return subscriberInfo
339     }
340
341     private fun generateCloudConfiguration(lcpCloudRegionId: String?, tenantId: String?): CloudConfiguration {
342         val cloudConfiguration = CloudConfiguration(lcpCloudRegionId, tenantId)
343         if (lcpCloudRegionId != null) {
344             cloudOwnerService.enrichCloudConfigurationWithCloudOwner(cloudConfiguration, lcpCloudRegionId)
345         }
346         return cloudConfiguration
347     }
348
349     private fun generateRelatedInstances(relatedInstances: Map<String, ModelInfo>): MutableList<RelatedInstance> {
350         return relatedInstances.entries.stream()
351                 .map { RelatedInstance(it.value, it.key) }
352                 .collect(Collectors.toList())
353     }
354
355     private fun generateRequestInfo(instanceName: String?, resourceType: ResourceType?, rollbackOnFailure: Boolean?, productFamilyId: String?, userId: String): BaseResourceInstantiationRequestDetails.RequestInfo {
356         return BaseResourceInstantiationRequestDetails.RequestInfo(
357                 if (resourceType == null) null else getUniqueNameIfNeeded(instanceName, resourceType, false),
358                 productFamilyId,
359                 VID_SOURCE,
360                 rollbackOnFailure,
361                 userId)
362
363     }
364
365     private fun getUniqueNameIfNeeded(name: String?, resourceType: ResourceType, isBulk: Boolean): String? {
366         return if (StringUtils.isNotEmpty(name)) {
367             if (isBulk) asyncInstantiationBL.getUniqueName(name, resourceType) else name
368         } else {
369             null
370         }
371     }
372
373     private fun generateUserParamList(): List<ServiceInstantiationRequestDetails.UserParamNameAndValue> {
374         return emptyList()
375     }
376
377     fun generateMacroServicePre1806InstantiationRequest(payload: ServiceInstantiation, userId: String): RequestDetailsWrapper<ServiceInstantiationRequestDetails> {
378         val requestInfo = ServiceInstantiationRequestDetails.RequestInfo(payload.instanceName, payload.productFamilyId, VID_SOURCE, payload.isRollbackOnFailure, userId)
379         val userParams = generateUserParamsNameAndValue(payload.instanceParams)
380         val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, false, userParams)
381         val subscriberInfo = generateSubscriberInfoPre1806(payload)
382         val project = if (payload.projectName != null) ServiceInstantiationRequestDetails.Project(payload.projectName) else null
383         val owningEntity = ServiceInstantiationRequestDetails.ServiceInstantiationOwningEntity(payload.owningEntityId, payload.owningEntityName)
384         val cloudConfiguration = generateCloudConfiguration(payload.lcpCloudRegionId, payload.tenantId)
385         val relatedInstanceList = generateRelatedInstanceListForVrfEntry(payload.vrfs)
386
387         return RequestDetailsWrapper(ServiceInstantiationPre1806RequestDetails(
388                 payload.modelInfo,
389                 owningEntity,
390                 subscriberInfo,
391                 project,
392                 requestInfo,
393                 requestParameters,
394                 cloudConfiguration,
395                 relatedInstanceList))
396     }
397
398     private fun generateUserParamsNameAndValue(instanceParams: List<Map<String, String>>): List<ServiceInstantiationRequestDetails.UserParamNameAndValue> {
399         return instanceParams.getOrElse(0) {emptyMap()}.map{ x-> ServiceInstantiationRequestDetails.UserParamNameAndValue(x.key, x.value)}
400     }
401
402     private fun generateSubscriberInfoPre1806(payload: ServiceInstantiation): SubscriberInfo {
403         val subscriberInfo = SubscriberInfo()
404         subscriberInfo.globalSubscriberId = payload.globalSubscriberId
405         subscriberInfo.subscriberName = payload.subscriberName
406         return subscriberInfo
407     }
408
409     private fun generateRelatedInstanceListForVrfEntry(vrfEntries: MutableMap<String, VrfEntry>): List<RelatedInstance> {
410         //fe send map of vrfs, with maps of networks and vpns, but actually we expect to only one vpn and one network
411         return if (vrfEntries.isEmpty() || vrfEntries.values.first().vpns.isEmpty() || vrfEntries.values.first().networks.isEmpty()) emptyList()
412         else {
413             val vpn = vrfEntries.values.first().vpns.values.first()
414             val network = vrfEntries.values.first().networks.values.first()
415             listOf(vpn, network).map { RelatedInstance(it.modelInfo, it.instanceId, it.instanceName) }
416         }
417     }
418
419     private fun generateMacroServiceInstantiationRequestParams(payload: ServiceInstantiation, serviceInstanceName: String?, jobId: UUID?): List<UserParamTypes> {
420         val userParams = generateServiceInstantiationServicesList(payload, serviceInstanceName, createServiceInstantiationVnfList(jobId, payload))
421
422         return userParams.plus(homingSolution())
423     }
424
425     private fun homingSolution(): List<UserParamTypes> {
426         return if (featureManager.isActive(Features.FLAG_DISABLE_HOMING)) {
427             listOf(ServiceInstantiationRequestDetails.HomingSolution(DISABLED_HOMING_VALUE))
428         } else {
429             listOf()
430         }
431     }
432 }