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