Fix multiple instantations via serviceOrder
[externalapi/nbi.git] / src / main / java / org / onap / nbi / apis / serviceorder / workflow / PostSoProcessor.java
1 /**
2  * Copyright (c) 2018 Orange
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14
15 package org.onap.nbi.apis.serviceorder.workflow;
16
17 import java.io.IOException;
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Map.Entry;
24 import java.util.stream.Collectors;
25 import java.util.Random;
26
27 import org.onap.nbi.apis.servicecatalog.ServiceSpecificationService;
28 import org.onap.nbi.apis.serviceorder.SoClient;
29 import org.onap.nbi.apis.serviceorder.model.ServiceCharacteristic;
30 import org.onap.nbi.apis.serviceorder.model.ServiceOrder;
31 import org.onap.nbi.apis.serviceorder.model.ServiceOrderItem;
32 import org.onap.nbi.apis.serviceorder.model.StateType;
33 import org.onap.nbi.apis.serviceorder.model.ServiceStateType;
34 import org.onap.nbi.apis.serviceorder.model.consumer.CloudConfiguration;
35 import org.onap.nbi.apis.serviceorder.model.consumer.CreateE2EServiceInstanceResponse;
36 import org.onap.nbi.apis.serviceorder.model.consumer.CreateMacroServiceInstanceResponse;
37 import org.onap.nbi.apis.serviceorder.model.consumer.CreateServiceInstanceResponse;
38 import org.onap.nbi.apis.serviceorder.model.consumer.MSOE2EPayload;
39 import org.onap.nbi.apis.serviceorder.model.consumer.MSOPayload;
40 import org.onap.nbi.apis.serviceorder.model.consumer.ModelInfo;
41 import org.onap.nbi.apis.serviceorder.model.consumer.OwningEntity;
42 import org.onap.nbi.apis.serviceorder.model.consumer.ParametersModel;
43 import org.onap.nbi.apis.serviceorder.model.consumer.Project;
44 import org.onap.nbi.apis.serviceorder.model.consumer.RequestDetails;
45 import org.onap.nbi.apis.serviceorder.model.consumer.RequestInfo;
46 import org.onap.nbi.apis.serviceorder.model.consumer.RequestParameters;
47 import org.onap.nbi.apis.serviceorder.model.consumer.ResourceModel;
48 import org.onap.nbi.apis.serviceorder.model.consumer.ServiceModel;
49 import org.onap.nbi.apis.serviceorder.model.consumer.SubscriberInfo;
50 import org.onap.nbi.apis.serviceorder.model.consumer.UserParams;
51 import org.onap.nbi.apis.serviceorder.model.consumer.VFModelInfo;
52 import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderInfo;
53 import org.onap.nbi.apis.serviceorder.service.ServiceOrderService;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56 import org.springframework.beans.factory.annotation.Autowired;
57 import org.springframework.beans.factory.annotation.Value;
58 import org.springframework.http.ResponseEntity;
59 import org.springframework.stereotype.Service;
60 import org.springframework.util.CollectionUtils;
61 import com.fasterxml.jackson.databind.JsonNode;
62 import com.fasterxml.jackson.databind.ObjectMapper;
63 import com.fasterxml.jackson.databind.node.ArrayNode;
64 import com.fasterxml.jackson.databind.node.ObjectNode;
65
66 @Service
67 public class PostSoProcessor {
68
69     private static final Logger LOGGER = LoggerFactory.getLogger(PostSoProcessor.class);
70
71     @Value("${onap.lcpCloudRegionId}")
72     private String lcpCloudRegionId;
73
74     @Value("${onap.tenantId}")
75     private String tenantId;
76
77     @Value("${so.owning.entity.id}")
78     private String soOwningEntityId;
79
80     @Value("${so.owning.entity.name}")
81     private String soOwningEntityName;
82
83     @Value("${so.project.name}")
84     private String soProjectName;
85
86     @Value("${onap.cloudOwner}")
87     private String cloudOwner;
88     
89     @Value("${onap.k8sCloudOwner}")
90         private String k8sCloudOwner;
91
92         @Value("${onap.k8sCloudRegionId}")
93         private String k8sCloudRegionId;
94
95         @Value("${k8s-rb-profile-name}")
96         private String k8sRbProfileName;
97
98     @Autowired
99     private ServiceOrderService serviceOrderService;
100
101     @Autowired
102     private SoClient soClient;
103     
104     @Autowired
105     ServiceSpecificationService serviceSpecificationService;
106
107     public ResponseEntity<CreateServiceInstanceResponse> postServiceOrderItem(ServiceOrderInfo serviceOrderInfo,
108             ServiceOrderItem serviceOrderItem) {
109         ResponseEntity<CreateServiceInstanceResponse> response = null;
110         try {
111             response = postSORequest(serviceOrderItem, serviceOrderInfo);
112         } catch (NullPointerException e) {
113             LOGGER.error("Unable to create service instance for serviceOrderItem.id=" + serviceOrderItem.getId(), e);
114             response = null;
115         }
116         return response;
117     }
118
119     public ResponseEntity<CreateE2EServiceInstanceResponse> postE2EServiceOrderItem(ServiceOrderInfo serviceOrderInfo,
120             ServiceOrderItem serviceOrderItem, ServiceOrder serviceOrder) {
121         ResponseEntity<CreateE2EServiceInstanceResponse> response;
122         try {
123             response = postE2ESORequest(serviceOrderItem, serviceOrderInfo, serviceOrder);
124         } catch (NullPointerException e) {
125             LOGGER.error("Unable to create service instance for serviceOrderItem.id=" + serviceOrderItem.getId(), e);
126             response = null;
127         }
128         return response;
129     }
130
131     public ResponseEntity<CreateMacroServiceInstanceResponse> postMacroServiceOrderItem(ServiceOrderInfo serviceOrderInfo,
132             ServiceOrderItem serviceOrderItem) {
133         ResponseEntity<CreateMacroServiceInstanceResponse> response = null;
134         try {
135             // For Macro Flow
136             response = postSOMacroRequest(serviceOrderItem, serviceOrderInfo);
137         } catch (NullPointerException e) {
138             LOGGER.error("Unable to create service instance for serviceOrderItem.id=" + serviceOrderItem.getId(), e);
139             response = null;
140         }
141         return response;
142     }
143     
144     private ResponseEntity<CreateServiceInstanceResponse> postSORequest(ServiceOrderItem serviceOrderItem,
145             ServiceOrderInfo serviceOrderInfo) {
146         RequestDetails requestDetails = buildSoRequest(serviceOrderItem, serviceOrderInfo);
147         MSOPayload msoPayload = new MSOPayload(requestDetails);
148         ResponseEntity<CreateServiceInstanceResponse> response = null;
149
150         switch (serviceOrderItem.getAction()) {
151             case ADD:
152                 response = soClient.callCreateServiceInstance(msoPayload);
153                 break;
154             case DELETE:
155                 response = soClient.callDeleteServiceInstance(msoPayload, serviceOrderItem.getService().getId());
156                 break;
157             case MODIFY:
158                 if (StateType.INPROGRESS_MODIFY_ITEM_TO_CREATE == serviceOrderItem.getState()) {
159                     response = soClient.callCreateServiceInstance(msoPayload);
160                 }
161                 if (StateType.ACKNOWLEDGED == serviceOrderItem.getState()) {
162                     response = soClient.callDeleteServiceInstance(msoPayload, serviceOrderItem.getService().getId());
163                 }
164                 break;
165             default:
166                 break;
167         }
168         return response;
169     }
170
171     private ResponseEntity<CreateE2EServiceInstanceResponse> postE2ESORequest(ServiceOrderItem serviceOrderItem,
172             ServiceOrderInfo serviceOrderInfo, ServiceOrder serviceOrder) {
173         ServiceModel service = buildE2ESoRequest(serviceOrderItem,
174                 serviceOrderInfo.getServiceOrderItemInfos().get(serviceOrderItem.getId()).getCatalogResponse(),
175                 serviceOrderInfo.getSubscriberInfo(), serviceOrder);
176         MSOE2EPayload msoE2EPayload = new MSOE2EPayload(service);
177         ResponseEntity<CreateE2EServiceInstanceResponse> response = null;
178         switch (serviceOrderItem.getAction()) {
179             case ADD:
180                 response = soClient.callE2ECreateServiceInstance(msoE2EPayload);
181                 break;
182             case DELETE:
183                 response = soClient.callE2EDeleteServiceInstance(service.getGlobalSubscriberId(),
184                         service.getServiceType(), serviceOrderItem.getService().getId());
185                 break;
186             case MODIFY:
187             //EXT-API supports E2E service activation/deactivation with action=modify and seviceState=active/inactive
188                 boolean isActivateReq = ServiceStateType.ACTIVE == serviceOrderItem.getService().getServiceState() ||
189                                 ServiceStateType.INACTIVE == serviceOrderItem.getService().getServiceState();
190
191                 if (ServiceStateType.ACTIVE == serviceOrderItem.getService().getServiceState()) {
192                         response = soClient.callServiceActivationE2EService(service.getGlobalSubscriberId(),
193                             service.getServiceType(), serviceOrderItem.getService().getId(),"activate");
194                 }
195                 if (ServiceStateType.INACTIVE == serviceOrderItem.getService().getServiceState()) {
196                         response = soClient.callServiceActivationE2EService(service.getGlobalSubscriberId(),
197                             service.getServiceType(), serviceOrderItem.getService().getId(),"deactivate");
198                 }
199                 //Other E2E service modification follows Deletion followed by activation.
200                 //For service modification, do not send serviceState=active/inactive
201                 if (!isActivateReq && StateType.INPROGRESS_MODIFY_ITEM_TO_CREATE == serviceOrderItem.getState()) {
202                     response = soClient.callE2ECreateServiceInstance(msoE2EPayload);
203                 }
204                 if (!isActivateReq && StateType.ACKNOWLEDGED == serviceOrderItem.getState()) {
205                     response = soClient.callE2EDeleteServiceInstance(service.getGlobalSubscriberId(),
206                             service.getServiceType(), serviceOrderItem.getService().getId());
207                 }
208                 break;
209             default:
210                 break;
211         }
212         return response;
213     }
214  
215     private ResponseEntity<CreateMacroServiceInstanceResponse> postSOMacroRequest(ServiceOrderItem serviceOrderItem,
216                             ServiceOrderInfo serviceOrderInfo) {
217       
218       String serviceModuleName = (String) serviceOrderInfo.getServiceOrderItemInfos().get(serviceOrderItem.getId())
219             .getCatalogResponse().get("name");
220
221       RequestDetails requestDetails = buildSoMacroRequest(serviceOrderItem, serviceOrderInfo);
222       MSOPayload msoMacroPayload = new MSOPayload(requestDetails);
223       ResponseEntity<CreateMacroServiceInstanceResponse> response = null;
224
225       switch (serviceOrderItem.getAction()) {
226         case ADD:
227           response = soClient.callMacroCreateServiceInstance(msoMacroPayload);
228           break;
229         case DELETE:
230            response = soClient.callMacroDeleteServiceInstance(msoMacroPayload,
231            serviceOrderItem.getService().getId());
232           break;
233         case MODIFY:
234           if (StateType.INPROGRESS_MODIFY_ITEM_TO_CREATE == serviceOrderItem.getState()) {
235             // response = soClient.callCreateServiceInstance(msoPayload);
236           }
237           if (StateType.ACKNOWLEDGED == serviceOrderItem.getState()) {
238             // response = soClient.callDeleteServiceInstance(msoPayload,
239             // serviceOrderItem.getService().getId());
240           }
241           break;
242         default:
243           break;
244       }
245       return response;
246     }
247     
248     /**
249      * Build SO MACRO CREATE request from the ServiceOrder and catalog informations from SDC
250      *
251      * @param orderItem
252      * @param serviceOrderInfo
253      * @param subscriberInfo
254      * @return
255      */
256     private RequestDetails buildSoMacroRequest(ServiceOrderItem orderItem, ServiceOrderInfo serviceOrderInfo) {
257       
258         RequestDetails requestDetails = new RequestDetails();
259                 Map<String, Object> sdcInfos = serviceOrderInfo.getServiceOrderItemInfos().get(orderItem.getId())
260                                 .getCatalogResponse();
261
262                 String id = orderItem.getService().getServiceSpecification().getId();
263                 Map responseChildRes = serviceSpecificationService.get(id);
264                 ArrayList<Map<String, Object>> resourseSpecificationArray = (ArrayList<Map<String, Object>>) responseChildRes
265                                 .get("resourceSpecification");
266
267                 Map<String, Object> resourseSpecificationMap = resourseSpecificationArray.get(0);
268
269                 Map serviceInstanceParam = (Map) resourseSpecificationMap.get("serviceInstanceParams");
270                 Map instanceSpecification = (Map) resourseSpecificationMap.get("InstanceSpecification");
271                 ArrayList<VFModelInfo> childResourceSpecification = (ArrayList<VFModelInfo>) resourseSpecificationMap
272                                 .get("childResourceSpecification");
273                 
274                 HashMap<String, Object> instanceParamsFromServiceCharacteristics = retrieveInstanceParamsFromServiceCharacteristics(
275                                 orderItem.getService().getServiceCharacteristic());
276                 
277                 HashMap<String, Object> instanceParams = (HashMap<String, Object>) buildAndDistinguishServiceAndVnfLevelParams(
278                                 instanceParamsFromServiceCharacteristics, instanceSpecification, serviceInstanceParam);
279
280                 HashMap<String, Object> vnfInstanceParams = (HashMap<String, Object>) instanceParams.get("vnf");
281                 List<Object> serviceObject = new ArrayList<>();
282
283                 ArrayList<Object> vnfInstanceParam = new ArrayList<>();
284
285                 //Differentiating vnf with cnf(Can be discussed and improved)
286                 if (instanceSpecification.get("public_net_id") != null) {
287                         Map<String, Object> instanceParam = new HashMap<>();
288                         //Merge instanceSpecification with vnfInstanceParams
289                         instanceSpecification.putAll(vnfInstanceParams);
290                         vnfInstanceParam.add(instanceSpecification);
291                 } else {
292                         //if skip_post_instantiation_configuration is true then add k8s-rb-profile-name
293                         if(instanceSpecification.get("skip_post_instantiation_configuration").equals(true))
294                                 vnfInstanceParams.put("k8s-rb-profile-name", k8sRbProfileName);
295                         vnfInstanceParam.add(vnfInstanceParams);
296                 }
297
298                 List resSpec = (ArrayList) sdcInfos.get("resourceSpecification");
299                 Map resSpecMap = (Map) resSpec.get(0);
300
301                 Map<String, String> vnfInfoObject = new HashMap<>();
302                 vnfInfoObject.put("modelName", (String) resSpecMap.get("name"));
303                 vnfInfoObject.put("modelVersionId", (String) resSpecMap.get("id"));
304                 vnfInfoObject.put("modelInvariantUuid", (String) resSpecMap.get("resourceInvariantUUID"));
305                 vnfInfoObject.put("modelVersion", (String) resSpecMap.get("version"));
306                 vnfInfoObject.put("modelCustomizationId", (String) resSpecMap.get("modelCustomizationId"));
307                 vnfInfoObject.put("modelInstanceName", (String) resSpecMap.get("resourceInstanceName"));
308
309                 //initialization
310                 CloudConfiguration cloudConfiguration = null;
311
312                 //Differentiating vnf with cnf(Can be discussed and improved)
313                 if (instanceSpecification.get("public_net_id") != null) {
314                         cloudConfiguration = new CloudConfiguration(lcpCloudRegionId, tenantId, cloudOwner);
315                 } else {
316                         cloudConfiguration = new CloudConfiguration(k8sCloudRegionId, tenantId, k8sCloudOwner);
317                 }
318
319                 Map<String, String> platformName = new HashMap<>();
320                 platformName.put("platformName", "test");
321
322                 Map<String, String> lob = new HashMap<>();
323                 lob.put("lineOfBusinessName", "LOB-Demonstration");
324
325                 //Create a random variable that will be concatanate to the instanceName
326                 Random rand = new Random();
327                 int upperbound = 100000;
328                 //generate random values from 0-upperbound
329                 int int_random = rand.nextInt(upperbound); 
330                 
331                 String vnfInstanceNameTmp = (String) resSpecMap.get("resourceInstanceName");
332                 String vnfInstanceName = vnfInstanceNameTmp + int_random;
333                 
334                 Map<String, Object> vnfModel = new HashMap<>();
335                 vnfModel.put("modelInfo", vnfInfoObject);
336                 vnfModel.put("cloudConfiguration", cloudConfiguration);
337                 vnfModel.put("platform", platformName);
338                 vnfModel.put("lineOfBusiness", lob);
339                 vnfModel.put("productFamilyId", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb");
340                 vnfModel.put("instanceName", vnfInstanceName);
341                 vnfModel.put("instanceParams", vnfInstanceParam);
342
343                 List<Object> vfModulesObjects = new ArrayList<>();
344                 ArrayList<Map<String, Object>> vfInstanceParam = new ArrayList<>();
345
346                 //Differentiate CNF from VNF
347                 if (instanceSpecification.get("public_net_id") != null) {
348                         vfInstanceParam.add(instanceSpecification);
349                         
350                 } else {
351                         Map<String, Object> instanceParam = new HashMap<>();
352                         if(instanceSpecification.get("skip_post_instantiation_configuration").equals(true))
353                                 instanceParam.put("k8s-rb-profile-name", k8sRbProfileName);
354                         vfInstanceParam.add(instanceParam);
355                 }
356                 
357                 for (VFModelInfo crsObject : childResourceSpecification) {
358                         Map<String, Object> vfModuleObject = new HashMap<>();
359                         Map<String, String> vfModuleInfo = new HashMap<>();
360
361                         //generate random values from 0-upperbound
362                         int_random = rand.nextInt(upperbound); 
363                 
364                         String vfmoduleInstanceNameTmp = (String) crsObject.getModelName();
365                         String vfmoduleInstanceName = vfmoduleInstanceNameTmp + int_random;     
366                 
367                         vfModuleInfo.put("modelName", crsObject.getModelName());
368                         vfModuleInfo.put("modelVersionId", crsObject.getModelUuid());
369                         vfModuleInfo.put("modelInvariantUuid", crsObject.getModelInvariantUuid());
370                         vfModuleInfo.put("modelVersion", crsObject.getModelVersion());
371                         vfModuleInfo.put("modelCustomizationId", crsObject.getModelCustomizationUuid());
372                         vfModuleObject.put("modelInfo", vfModuleInfo);
373                         vfModuleObject.put("instanceName", vfmoduleInstanceName);
374                         vfModuleObject.put("instanceParams", vfInstanceParam);
375
376                         vfModulesObjects.add(vfModuleObject);
377                 }
378                 vnfModel.put("vfModules", vfModulesObjects);
379
380                 List<Object> vnfObjects = new ArrayList<>();
381                 vnfObjects.add(vnfModel);
382
383                 Map<String, Object> vnfData = new HashMap<>();
384                 vnfData.put("vnfs", vnfObjects);
385
386                 ModelInfo serviceModelInfo = new ModelInfo();
387                 serviceModelInfo.setModelType("service");
388                 serviceModelInfo.setModelInvariantId((String) sdcInfos.get("invariantUUID"));
389                 serviceModelInfo.setModelVersionId(orderItem.getService().getServiceSpecification().getId());
390                 serviceModelInfo.setModelName((String) sdcInfos.get("name"));
391                 serviceModelInfo.setModelVersion((String) sdcInfos.get("version"));
392
393                 // Adding List of instanceParams for service
394                 // We can add instanceParams Key Value in Map Object and add it to the List, for
395                 // For now it is empty to comply with so request
396
397                 List<Map<String, String>> listOfServiceLevelInstanceParams = new ArrayList<>();
398                 Map<String, String> serviceInstanceParams = (HashMap<String, String>) instanceParams.get("service");
399                 listOfServiceLevelInstanceParams.add(serviceInstanceParams);
400                 
401                 Map<String, Object> serviceData = new HashMap<>();
402                 serviceData.put("instanceParams", listOfServiceLevelInstanceParams);
403                 serviceData.put("instanceName", orderItem.getService().getName());
404                 serviceData.put("resources", vnfData);
405                 serviceData.put("modelInfo", serviceModelInfo);
406
407                 Map<String, String> homingObject = new HashMap<>();
408                 homingObject.put("Homing_Solution", "none");
409                 serviceObject.add(homingObject);
410
411                 Map<String, Object> serviceObject1 = new HashMap<>();
412                 serviceObject1.put("service", serviceData);
413                 serviceObject.add(serviceObject1);
414                 requestDetails.setSubscriberInfo(serviceOrderInfo.getSubscriberInfo());
415
416                 ModelInfo modelInfo = new ModelInfo();
417                 modelInfo.setModelType("service");
418                 modelInfo.setModelInvariantId((String) sdcInfos.get("invariantUUID"));
419                 modelInfo.setModelVersionId(orderItem.getService().getServiceSpecification().getId());
420                 modelInfo.setModelName((String) sdcInfos.get("name"));
421                 modelInfo.setModelVersion((String) sdcInfos.get("version"));
422                 requestDetails.setModelInfo(modelInfo);
423
424                 RequestInfo requestInfo = new RequestInfo();
425                 requestInfo.setInstanceName(orderItem.getService().getName());
426                 requestInfo.setSource("VID");
427                 requestInfo.setSuppressRollback(false);
428                 requestInfo.setRequestorId("NBI");
429                 requestInfo.setProductFamilyId("a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb");
430                 requestDetails.setRequestInfo(requestInfo);
431
432                 // We are taking RequestParameters as map because it has UserParams which gives value as
433                 // "name" : "service"
434                 // "value" : "", which SO is not accepting
435                 Map<String, Object> requestParameters = new HashMap<>();
436
437                 // Get value from serviceOrder request or generate one
438                 String serviceTypeFromJson = orderItem.getService().getServicetype();
439                 requestParameters.put("subscriptionServiceType",
440                                 serviceTypeFromJson != null ? serviceTypeFromJson : (String) sdcInfos.get("name"));
441                 requestParameters.put("userParams", serviceObject);
442                 requestParameters.put("aLaCarte", false);
443                 requestDetails.setRequestParameters(requestParameters);
444                 requestDetails.setCloudConfiguration(cloudConfiguration);
445
446                 OwningEntity owningEntity = new OwningEntity();
447                 owningEntity.setOwningEntityId(soOwningEntityId);
448                 owningEntity.setOwningEntityName(soOwningEntityName);
449                 requestDetails.setOwningEntity(owningEntity);
450
451                 Project project = new Project();
452                 project.setProjectName(soProjectName);
453
454                 requestDetails.setProject(project);
455         return requestDetails;
456         }
457
458     /**
459      * Build SO CREATE request from the ServiceOrder and catalog informations from SDC
460      *
461      * @param orderItem
462      * @param serviceOrderInfo
463      * @return
464      */
465     private RequestDetails buildSoRequest(ServiceOrderItem orderItem, ServiceOrderInfo serviceOrderInfo) {
466         RequestDetails requestDetails = new RequestDetails();
467
468         requestDetails.setSubscriberInfo(serviceOrderInfo.getSubscriberInfo());
469         Map<String, Object> sdcInfos =
470                 serviceOrderInfo.getServiceOrderItemInfos().get(orderItem.getId()).getCatalogResponse();
471         ModelInfo modelInfo = new ModelInfo();
472         modelInfo.setModelType("service");
473         modelInfo.setModelInvariantId((String) sdcInfos.get("invariantUUID"));
474         modelInfo.setModelNameVersionId(orderItem.getService().getServiceSpecification().getId());
475         modelInfo.setModelVersionId(orderItem.getService().getServiceSpecification().getId());
476         modelInfo.setModelName((String) sdcInfos.get("name"));
477         modelInfo.setModelVersion((String) sdcInfos.get("version"));
478         requestDetails.setModelInfo(modelInfo);
479
480         RequestInfo requestInfo = new RequestInfo();
481         requestInfo.setInstanceName(orderItem.getService().getName());
482         requestInfo.setSource("VID");
483         requestInfo.setSuppressRollback(false);
484         requestInfo.setRequestorId("NBI");
485         requestDetails.setRequestInfo(requestInfo);
486
487         RequestParameters requestParameters = new RequestParameters();
488         
489         String serviceTypeFromJson = orderItem.getService().getServicetype();
490         requestParameters.setSubscriptionServiceType(serviceTypeFromJson != null ? serviceTypeFromJson:(String) sdcInfos.get("name"));
491         requestParameters.setUserParams(
492                 retrieveUserParamsFromServiceCharacteristics(orderItem.getService().getServiceCharacteristic()));
493         requestParameters.setaLaCarte(true);
494         requestParameters.setTestApi("GR_API");
495         requestDetails.setRequestParameters(requestParameters);
496
497         CloudConfiguration cloudConfiguration = new CloudConfiguration(lcpCloudRegionId, tenantId, cloudOwner);
498         requestDetails.setCloudConfiguration(cloudConfiguration);
499
500         OwningEntity owningEntity = new OwningEntity();
501         owningEntity.setOwningEntityId(serviceOrderInfo.getOwningEntityId());
502         owningEntity.setOwningEntityName(soOwningEntityName);
503         requestDetails.setOwningEntity(owningEntity);
504
505         Project project = new Project();
506         project.setProjectName(soProjectName);
507
508         requestDetails.setProject(project);
509
510         return requestDetails;
511     }
512
513     /**
514      * Build E2E SO CREATE request from the ServiceOrder and catalog informations from SDC
515      *
516      * @param serviceOrderItem
517      * @param serviceOrder
518      * @param sdcInfos
519      * @return
520      */
521     // ServiceOrderItem serviceOrderItem --> orderItem?
522     private ServiceModel buildE2ESoRequest(ServiceOrderItem serviceOrderItem, Map<String, Object> sdcInfos,
523             SubscriberInfo subscriberInfo, ServiceOrder serviceOrder) {
524
525         subscriberInfo.getGlobalSubscriberId();
526         ServiceModel service = new ServiceModel();
527         service.setName(serviceOrderItem.getService().getName());
528         service.setDescription(serviceOrder.getDescription());
529         service.setServiceUuid(serviceOrderItem.getService().getServiceSpecification().getId());
530         service.setServiceInvariantUuid((String) sdcInfos.get("invariantUUID"));
531         service.setGlobalSubscriberId(subscriberInfo.getGlobalSubscriberId());
532         String serviceTypeFromJson = serviceOrderItem.getService().getServicetype();
533         service.setServiceType(serviceTypeFromJson != null ? serviceTypeFromJson : (String) sdcInfos.get("name"));
534         ParametersModel parameters = new ParametersModel();
535         ArrayList<ResourceModel> resources = new ArrayList();
536
537         ArrayList<Object> resourceObjects = (ArrayList<Object>) sdcInfos.get("resourceSpecification");
538
539         for (int i = 0; i < resourceObjects.size(); i++) {
540
541             ResourceModel resourceModel = new ResourceModel((Map<String, Object>) resourceObjects.get(i));
542             ParametersModel resourceParameters = new ParametersModel();
543             resourceModel.setParameters(resourceParameters);
544             resources.add(resourceModel);
545
546         }
547         parameters.setResources(resources);
548         List<UserParams> userParams =
549                 retrieveUserParamsFromServiceCharacteristics(serviceOrderItem.getService().getServiceCharacteristic());
550
551         // If there are ServiceCharacteristics add them to requestInputs
552         if (!userParams.isEmpty()) {
553             Map<String, String> requestInputs = new HashMap<String, String>();
554             for (int i = 0; i < userParams.size(); i++) {
555                 requestInputs.put(userParams.get(i).getName(), (String) userParams.get(i).getValue());
556             }
557
558             parameters.setRequestInputs(requestInputs);
559         }
560         service.setParameters(parameters);
561
562         return service;
563     }
564
565     /**
566      * Build a list of UserParams for the SO request by browsing a list of ServiceCharacteristics from
567      * SDC
568      */
569     private List<UserParams> retrieveUserParamsFromServiceCharacteristics(List<ServiceCharacteristic> characteristics) {
570         List<UserParams> userParams = new ArrayList<>();
571         UserParams userParam;
572
573         if (!CollectionUtils.isEmpty(characteristics)) {
574             for (ServiceCharacteristic characteristic : characteristics) {
575                 // Check is the characteristic is of type object, if proceed as before to allow for
576                 // backwards compatibility.
577                 if (characteristic.getValueType() != null && !characteristic.getValueType().isEmpty()
578                         && characteristic.getValueType().equals("object")) {
579                     ObjectMapper mapper = new ObjectMapper();
580                     JsonNode jsonNode = null;
581                     try {
582                         jsonNode = mapper.readTree(characteristic.getValue().getServiceCharacteristicValue());
583                     } catch (IOException e) {
584                         LOGGER.error("Failed to read object json {} , exception is ",
585                                 characteristic.getValue().getServiceCharacteristicValue(), e.getMessage());
586                     }
587                     ObjectNode objectNode = (ObjectNode) jsonNode;
588                     Iterator<Map.Entry<String, JsonNode>> iter = objectNode.fields();
589                     while (iter.hasNext()) {
590                         Map.Entry<String, JsonNode> entry = iter.next();
591                         if (!entry.getValue().isArray()) {
592                             userParam = new UserParams(entry.getKey(), entry.getValue().asText());
593                         } else {
594                             ArrayNode arrayNode = (ArrayNode) entry.getValue();
595                             String arrayNodeValueString = arrayNode.toString();
596                             userParam = new UserParams(entry.getKey(), arrayNodeValueString);
597                         }
598                         userParams.add(userParam);
599                     }
600                 }
601                 // as UserParams for all other types, boolean, string, integer etc
602                 else {
603                     userParam = new UserParams(characteristic.getName(),
604                             characteristic.getValue().getServiceCharacteristicValue());
605                     userParams.add(userParam);
606                 }
607             }
608         }
609
610         return userParams;
611     }
612     
613     /**
614          * Build a list of InstanceParams for the SO Macro request by browsing a list of
615          * ServiceCharacteristics
616          */
617         private HashMap<String, Object> retrieveInstanceParamsFromServiceCharacteristics(
618                         List<ServiceCharacteristic> characteristics) {
619
620                 HashMap<String, Object> instanceParams = new HashMap<>();
621
622                 if (!CollectionUtils.isEmpty(characteristics)) {
623                         for (ServiceCharacteristic characteristic : characteristics) {
624                                 // Check is the characteristic is of type object, if proceed as before to allow
625                                 // for
626                                 // backwards compatibility.
627                                 if (characteristic.getValueType() != null && !characteristic.getValueType().isEmpty()
628                                                 && characteristic.getValueType().equals("object")) {
629                                         ObjectMapper mapper = new ObjectMapper();
630                                         JsonNode jsonNode = null;
631                                         try {
632                                                 jsonNode = mapper.readTree(characteristic.getValue().getServiceCharacteristicValue());
633                                         } catch (IOException e) {
634                                                 LOGGER.error("Failed to read object json {} , exception is ",
635                                                                 characteristic.getValue().getServiceCharacteristicValue(), e.getMessage());
636                                         }
637                                         ObjectNode objectNode = (ObjectNode) jsonNode;
638                                         Iterator<Map.Entry<String, JsonNode>> iter = objectNode.fields();
639                                         while (iter.hasNext()) {
640                                                 Map.Entry<String, JsonNode> entry = iter.next();
641                                                 if (!entry.getValue().isArray()) {
642                                                         instanceParams.put(entry.getKey(), entry.getValue().asText());
643                                                 } else {
644                                                         ArrayNode arrayNode = (ArrayNode) entry.getValue();
645                                                         String arrayNodeValueString = arrayNode.toString();
646                                                         instanceParams.put(entry.getKey(), arrayNodeValueString);
647                                                 }
648                                         }
649                                 } else {
650                                         instanceParams.put(characteristic.getName(),
651                                                         characteristic.getValue().getServiceCharacteristicValue());
652                                 }
653                         }
654                 }
655
656                 return instanceParams;
657         }
658         
659         /**
660          * Build and distinguish InstanceParams at VNF Level and Service level and overwrite values from ServiceOrder JSON Request.
661          * Can be used as buildAndDistinguishServiceAndVnfLevelParams.get("vnf"); or buildAndDistinguishServiceAndVnfLevelParams.get("cnf");
662          */
663         private Map<String, Object> buildAndDistinguishServiceAndVnfLevelParams(
664                         Map<String, Object> instanceParamsFromServiceCharacteristic, Map<String, Object> existingVNFParams,
665                         Map<String, Object> existingServiceParams) {
666
667                 //To be used by passing key as "vnf" or "service" for respective instanceParams
668                 Map<String, Object> serviceAndVNFLevelInstanceParams = new HashMap<>();
669
670                 Map<String, Object> resultVNFParams = new HashMap<>();
671                 Map<String, Object> resultServiceParams = new HashMap<>();
672
673                 // First Filter VNF level Params From Service Characteristics and overwrite
674                 // values
675                 resultVNFParams = instanceParamsFromServiceCharacteristic.entrySet().stream()
676                                 .filter(entry -> existingVNFParams.containsKey(entry.getKey()))
677                                 .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
678
679                 //Add it as VNF level Params
680                 serviceAndVNFLevelInstanceParams.put("vnf", resultVNFParams);
681
682                 // Filter VNF level Params From Service Level
683                 existingServiceParams.entrySet().removeIf(e -> existingVNFParams.containsKey(e.getKey()));
684
685                 // Filter Service level Params From Service Characteristics and overwrite values
686                 resultServiceParams = instanceParamsFromServiceCharacteristic.entrySet().stream()
687                                 .filter(entry -> existingServiceParams.containsKey(entry.getKey()))
688                                 .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
689
690                 //Add it as Service level params
691                 serviceAndVNFLevelInstanceParams.put("service", resultServiceParams);
692
693                 return serviceAndVNFLevelInstanceParams;
694
695         }
696
697 }