Updated fields on sniro request
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / buildingblock / SniroHomingV2.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 - 2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.bpmn.buildingblock;
22
23 import static org.apache.commons.lang3.StringUtils.*;
24
25 import java.time.Duration;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.UUID;
30
31 import org.apache.commons.lang.SerializationUtils;
32 import org.camunda.bpm.engine.delegate.BpmnError;
33 import org.json.JSONArray;
34 import org.json.JSONObject;
35 import org.onap.so.bpmn.common.BuildingBlockExecution;
36 import org.onap.so.bpmn.core.json.JsonUtils;
37 import org.onap.so.bpmn.servicedecomposition.bbobjects.AllottedResource;
38 import org.onap.so.bpmn.servicedecomposition.bbobjects.CloudRegion;
39 import org.onap.so.bpmn.servicedecomposition.bbobjects.Customer;
40 import org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf;
41 import org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf;
42 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
43 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceProxy;
44 import org.onap.so.bpmn.servicedecomposition.bbobjects.VpnBondingLink;
45 import org.onap.so.bpmn.servicedecomposition.entities.GeneralBuildingBlock;
46 import org.onap.so.bpmn.servicedecomposition.generalobjects.License;
47 import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestContext;
48 import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestParameters;
49 import org.onap.so.bpmn.servicedecomposition.homingobjects.Candidate;
50 import org.onap.so.bpmn.servicedecomposition.homingobjects.CandidateType;
51 import org.onap.so.bpmn.servicedecomposition.homingobjects.SolutionCandidates;
52 import org.onap.so.bpmn.servicedecomposition.homingobjects.SolutionInfo;
53 import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoMetadata;
54 import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoServiceInstance;
55 import org.onap.so.client.exception.BadResponseException;
56 import org.onap.so.client.exception.ExceptionBuilder;
57
58 import org.onap.so.client.sniro.SniroClient;
59 import static org.onap.so.client.sniro.SniroValidator.*;
60
61 import org.onap.so.client.sniro.beans.Demand;
62 import org.onap.so.client.sniro.beans.LicenseInfo;
63 import org.onap.so.client.sniro.beans.ModelInfo;
64 import org.onap.so.client.sniro.beans.PlacementInfo;
65 import org.onap.so.client.sniro.beans.RequestInfo;
66 import org.onap.so.client.sniro.beans.ServiceInfo;
67 import org.onap.so.client.sniro.beans.SniroManagerRequest;
68 import org.onap.so.client.sniro.beans.SubscriberInfo;
69 import org.onap.so.db.catalog.beans.OrchestrationStatus;
70 import org.onap.so.logger.MsoLogger;
71 import org.springframework.beans.factory.annotation.Autowired;
72 import org.springframework.core.env.Environment;
73 import org.springframework.stereotype.Component;
74 import org.springframework.web.util.UriUtils;
75
76
77 /**
78  * The sniro homing building block obtains licensing and homing solutions for a given
79  * resource or set of resources.
80  *
81  * @author cb645j
82  *
83  */
84 @Component("SniroHoming")
85 public class SniroHomingV2 {
86
87         private static final MsoLogger log = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, SniroHomingV2.class);
88         private JsonUtils jsonUtils = new JsonUtils();
89         @Autowired
90         private Environment env;
91         @Autowired
92         private SniroClient client;
93         @Autowired
94         private ExceptionBuilder exceptionUtil;
95         private static final String MODEL_NAME = "modelName";
96         private static final String MODEL_INVARIANT_ID = "modelInvariantId";
97         private static final String MODEL_VERSION_ID = "modelVersionId";
98         private static final String MODEL_VERSION = "modelVersion";
99         private static final String SERVICE_RESOURCE_ID = "serviceResourceId";
100         private static final String RESOURCE_MODULE_NAME = "resourceModuleName";
101         private static final String RESOURCE_MODEL_INFO = "resourceModelInfo";
102         private static final String IDENTIFIER_TYPE = "identifierType";
103         private static final String INVENTORY_TYPE = "inventoryType";
104         private static final String SOLUTIONS = "solutions";
105         private static final String RESOURCE_MISSING_DATA = "Resource does not contain: ";
106         private static final String SERVICE_MISSING_DATA = "Service Instance does not contain: ";
107         private static final String UNPROCESSABLE = "422";
108         private static final int INTERNAL = 500;
109
110         /**
111          * Generates the request payload then sends to sniro manager to perform homing and
112          * licensing for the provided demands
113          *
114          * @param execution
115          */
116         public void callSniro(BuildingBlockExecution execution){
117                 log.debug("Started Sniro Homing Call Sniro");
118                 try{
119                         GeneralBuildingBlock bb = execution.getGeneralBuildingBlock();
120
121                         RequestContext requestContext = bb.getRequestContext();
122                         RequestParameters requestParams = requestContext.getRequestParameters();
123                         String requestId = requestContext.getMsoRequestId();
124
125                         ServiceInstance serviceInstance = bb.getCustomer().getServiceSubscription().getServiceInstances().get(0);
126                         Customer customer = bb.getCustomer();
127
128                         String timeout = execution.getVariable("timeout");
129                         if(isBlank(timeout)){
130                                 timeout = env.getProperty("sniro.manager.timeout", "PT30M");
131                         }
132
133                         SniroManagerRequest request = new SniroManagerRequest();
134
135                         RequestInfo requestInfo = buildRequestInfo(requestId, timeout);
136                         request.setRequestInformation(requestInfo);
137
138                         ServiceInfo serviceInfo = buildServiceInfo(serviceInstance);
139                         request.setServiceInformation(serviceInfo);
140
141                         PlacementInfo placementInfo = buildPlacementInfo(customer, requestParams);
142
143                         List<Demand> placementDemands = buildPlacementDemands(serviceInstance);
144                         placementInfo.setDemands(placementDemands);
145                         request.setPlacementInformation(placementInfo);
146
147                         LicenseInfo licenseInfo = new LicenseInfo();
148
149                         List<Demand> licenseDemands = buildLicenseDemands(serviceInstance);
150                         licenseInfo.setDemands(licenseDemands);
151                         request.setLicenseInformation(licenseInfo);
152
153                         if(placementDemands.size() > 0 || licenseDemands.size() > 0){
154                                 client.postDemands(request);
155                         }else{
156                                 log.debug(SERVICE_MISSING_DATA + "resources eligible for homing or licensing");
157                                 throw new BpmnError(UNPROCESSABLE, SERVICE_MISSING_DATA + "resources eligible for homing or licensing");
158                         }
159
160                         //Variables for ReceiveWorkflowMessage subflow
161                         execution.setVariable("asyncCorrelator", requestId);
162                         execution.setVariable("asyncMessageType", "SNIROResponse");
163                         execution.setVariable("asyncTimeout", timeout);
164
165                         log.trace("Completed Sniro Homing Call Sniro");
166                 }catch(BpmnError e){
167                         log.error(e);
168                         exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(e.getErrorCode()), e.getMessage());
169                 }catch(BadResponseException e){
170                         log.error(e);
171                         exceptionUtil.buildAndThrowWorkflowException(execution, 400, e.getMessage());
172                 }catch(Exception e){
173                         log.error(e);
174                         exceptionUtil.buildAndThrowWorkflowException(execution, INTERNAL, "Internal Error - occurred while preparing sniro request: " + e.getMessage());
175                 }
176         }
177
178         /**
179          * Validates, processes, and sets the homing and licensing solutions that are returned by
180          * sniro manager
181          *
182          * @param execution
183          * @param asyncResponse
184          */
185         public void processSolution(BuildingBlockExecution execution, String asyncResponse){
186                 log.trace("Started Sniro Homing Process Solution");
187                 try{
188                         //TODO improve handling multiple solutions but is dependent on sniro enhancing api + work with sniro conductor to improve "inventoryType" representation
189                         validateSolution(asyncResponse);
190                         ServiceInstance serviceInstance = execution.getGeneralBuildingBlock().getCustomer().getServiceSubscription().getServiceInstances().get(0);
191
192                         log.debug("Processing sniro manager asyncronous response");
193                         JSONObject response = new JSONObject(asyncResponse);
194                         if(response.has(SOLUTIONS)){
195                                 JSONObject allSolutions = response.getJSONObject(SOLUTIONS);
196                                 if(allSolutions.has("placementSolutions")){
197                                         JSONArray placementSolutions = allSolutions.getJSONArray("placementSolutions");
198                                         for(int i = 0; i < placementSolutions.length(); i++){
199                                                 JSONArray placements = placementSolutions.getJSONArray(i);
200                                                 processPlacementSolution(serviceInstance, placements, i);
201                                         }
202                                 }
203                                 if(allSolutions.has("licenseSolutions")){
204                                         JSONArray licenseSolutions = allSolutions.getJSONArray("licenseSolutions");
205                                         if(licenseSolutions.length() > 0){
206                                                 processLicenseSolution(serviceInstance, licenseSolutions);
207                                         }
208                                 }
209                         }else{
210                                 throw new BpmnError(UNPROCESSABLE, "Sniro Managers response does not contain: " + SOLUTIONS);
211                         }
212
213                         execution.setVariable("generalBuildingBlock", execution.getGeneralBuildingBlock());
214
215                         log.trace("Completed Sniro Homing Process Solution");
216                 }catch(BpmnError e){
217                         log.error(e);
218                         exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(e.getErrorCode()), e.getMessage());
219                 }catch(BadResponseException e){
220                         log.error(e);
221                         exceptionUtil.buildAndThrowWorkflowException(execution, 400, e.getMessage());
222                 }catch(Exception e){
223                         log.error(e);
224                         exceptionUtil.buildAndThrowWorkflowException(execution, INTERNAL, "Internal Error - occurred while processing sniro asynchronous response: " + e.getMessage());
225                 }
226         }
227
228         /**
229          * Builds the request information section for the homing/licensing request
230          *
231          * @throws Exception
232          */
233         private RequestInfo buildRequestInfo(String requestId, String timeout) throws Exception{
234                 log.trace("Building request information");
235                 RequestInfo requestInfo = new RequestInfo();
236                 if(requestId != null){
237                         String host = env.getProperty("mso.workflow.message.endpoint");
238                         String callbackUrl = host + "/" + UriUtils.encodePathSegment("SNIROResponse", "UTF-8") + "/" + UriUtils.encodePathSegment(requestId, "UTF-8");
239
240                         Duration d = Duration.parse(timeout);
241
242                         requestInfo.setTransactionId(requestId);
243                         requestInfo.setRequestId(requestId);
244                         requestInfo.setCallbackUrl(callbackUrl);
245                         requestInfo.setRequestType("create");
246                         requestInfo.setTimeout(d.getSeconds());
247
248                 } else{
249                         throw new BpmnError(UNPROCESSABLE, "Request Context does not contain: requestId");
250                 }
251                 return requestInfo;
252         }
253
254         /**
255          * Builds the request information section for the homing/licensing request
256          *
257          */
258         private ServiceInfo buildServiceInfo(ServiceInstance serviceInstance){
259                 log.trace("Building service information");
260                 ServiceInfo info = new ServiceInfo();
261                 ModelInfoServiceInstance modelInfo = serviceInstance.getModelInfoServiceInstance();
262                 if(isNotBlank(modelInfo.getModelInvariantUuid()) && isNotBlank(modelInfo.getModelUuid())){
263                         info.setServiceInstanceId(serviceInstance.getServiceInstanceId());
264                         if(modelInfo.getServiceType() != null && modelInfo.getServiceType().length() > 0){ //temp solution
265                                 info.setServiceName(modelInfo.getServiceType());
266                         }
267                         if(modelInfo.getServiceRole() != null){
268                                 info.setServiceRole(modelInfo.getServiceRole());
269                         }
270                         info.setModelInfo(buildModelInfo(modelInfo));
271                 }else{
272                         throw new BpmnError(UNPROCESSABLE, SERVICE_MISSING_DATA + MODEL_VERSION_ID + ", " + MODEL_INVARIANT_ID);
273                 }
274                 return info;
275         }
276
277         /**
278          * Builds initial section of placement info for the homing/licensing request
279          *
280          */
281         private PlacementInfo buildPlacementInfo(Customer customer, RequestParameters requestParams){
282                 PlacementInfo placementInfo = new PlacementInfo();
283                 if(customer != null){
284                         log.debug("Adding subscriber to placement information");
285                         SubscriberInfo subscriber = new SubscriberInfo();
286                         subscriber.setGlobalSubscriberId(customer.getGlobalCustomerId());
287                         subscriber.setSubscriberName(customer.getSubscriberName());
288                         subscriber.setSubscriberCommonSiteId(customer.getSubscriberCommonSiteId());
289                         placementInfo.setSubscriberInfo(subscriber);
290                         if(requestParams != null){
291                                 log.debug("Adding request parameters to placement information");
292                                 placementInfo.setRequestParameters(requestParams.toJsonString());
293                         }
294                 }else{
295                         throw new BpmnError(UNPROCESSABLE, SERVICE_MISSING_DATA + "customer");
296                 }
297                 return placementInfo;
298
299         }
300
301         /**
302          * Builds the placement demand list for the homing/licensing request
303          *
304          */
305         private List<Demand> buildPlacementDemands(ServiceInstance serviceInstance){
306                 log.trace("Building placement information demands");
307                 List<Demand> placementDemands = new ArrayList<Demand>();
308
309                 List<AllottedResource> allottedResourceList = serviceInstance.getAllottedResources();
310                 if(!allottedResourceList.isEmpty()){
311                         log.debug("Adding allotted resources to placement demands list");
312                         for(AllottedResource ar : allottedResourceList){
313                                 if(isBlank(ar.getId())){
314                                         ar.setId(UUID.randomUUID().toString());
315                                 }
316                                 Demand demand = buildDemand(ar.getId(), ar.getModelInfoAllottedResource());
317                                 addCandidates(ar, demand);
318                                 placementDemands.add(demand);
319                         }
320                 }
321                 List<VpnBondingLink> vpnBondingLinkList = serviceInstance.getVpnBondingLinks();
322                 if(!vpnBondingLinkList.isEmpty()){
323                         log.debug("Adding vpn bonding links to placement demands list");
324                         for(VpnBondingLink vbl:vpnBondingLinkList){
325                                 List<ServiceProxy> serviceProxyList = vbl.getServiceProxies();
326                                 for(ServiceProxy sp : serviceProxyList){
327                                         if(isBlank(sp.getId())){
328                                                 sp.setId(UUID.randomUUID().toString());
329                                         }
330                                         Demand demand = buildDemand(sp.getId(), sp.getModelInfoServiceProxy());
331                                         addCandidates(sp, demand);
332                                         placementDemands.add(demand);
333                                 }
334                         }
335                 }
336                 return placementDemands;
337         }
338
339         /**
340          * Builds the license demand list for the homing/licensing request
341          *
342          */
343         private List<Demand> buildLicenseDemands(ServiceInstance serviceInstance){
344                 log.trace("Building license information");
345                 List<Demand> licenseDemands = new ArrayList<Demand>();
346                 List<GenericVnf> vnfList = serviceInstance.getVnfs();
347                 if(!vnfList.isEmpty()){
348                         log.debug("Adding vnfs to license demands list");
349                         for(GenericVnf vnf : vnfList){
350                                 Demand demand = buildDemand(vnf.getVnfId(), vnf.getModelInfoGenericVnf());
351                                 licenseDemands.add(demand);
352                         }
353                 }
354                 return licenseDemands;
355         }
356
357         /**
358          * Builds a single demand object
359          *
360          */
361         private Demand buildDemand(String id, ModelInfoMetadata metadata){
362                 log.debug("Building demand for service or resource: " + id);
363                 Demand demand = new Demand();
364                 if(isNotBlank(id) && isNotBlank(metadata.getModelInstanceName())){
365                         demand.setServiceResourceId(id);
366                         demand.setResourceModuleName(metadata.getModelInstanceName());
367                         demand.setModelInfo(buildModelInfo(metadata));
368                 }else{
369                         throw new BpmnError(UNPROCESSABLE, RESOURCE_MISSING_DATA + "modelInstanceName");
370                 }
371                 return demand;
372         }
373
374         /**
375          * Builds the resource model info section
376          *
377          */
378         private ModelInfo buildModelInfo(ModelInfoMetadata metadata){
379                 ModelInfo object = new ModelInfo();
380                 String invariantUuid = metadata.getModelInvariantUuid();
381                 String modelUuid = metadata.getModelUuid();
382                 if(isNotBlank(invariantUuid) && isNotBlank(modelUuid)){
383                         object.setModelInvariantId(invariantUuid);
384                         object.setModelVersionId(modelUuid);
385                         object.setModelName(metadata.getModelName());
386                         object.setModelVersion(metadata.getModelVersion());
387                 }else if(isNotBlank(invariantUuid)){
388                         throw new BpmnError(UNPROCESSABLE, RESOURCE_MISSING_DATA + MODEL_VERSION_ID);
389                 }else{
390                         throw new BpmnError(UNPROCESSABLE, RESOURCE_MISSING_DATA + MODEL_INVARIANT_ID);
391                 }
392                 return object;
393         }
394
395         /**
396          * Adds required, excluded, and existing candidates to a demand
397          *
398          */
399         private void addCandidates(SolutionCandidates candidates, Demand demand){
400                 List<Candidate> required = candidates.getRequiredCandidates();
401                 List<Candidate> excluded = candidates.getExcludedCandidates();
402                 if(!required.isEmpty()){
403                         List<org.onap.so.client.sniro.beans.Candidate> cans = new ArrayList<org.onap.so.client.sniro.beans.Candidate>();
404                         for(Candidate c:required){
405                                 org.onap.so.client.sniro.beans.Candidate can = new org.onap.so.client.sniro.beans.Candidate();
406                                 org.onap.so.client.sniro.beans.CandidateType type = new org.onap.so.client.sniro.beans.CandidateType();
407                                 type.setName(c.getIdentifierType().getName());
408                                 can.setIdentifierType(type);
409                                 can.setIdentifiers(c.getIdentifiers());
410                                 can.setCloudOwner(c.getCloudOwner());
411                                 cans.add(can);
412                         }
413                         demand.setRequiredCandidates(cans);
414                 }
415                 if(!excluded.isEmpty()){
416                         List<org.onap.so.client.sniro.beans.Candidate> cans = new ArrayList<org.onap.so.client.sniro.beans.Candidate>();
417                         for(Candidate c:excluded){
418                                 org.onap.so.client.sniro.beans.Candidate can = new org.onap.so.client.sniro.beans.Candidate();
419                                 org.onap.so.client.sniro.beans.CandidateType type = new org.onap.so.client.sniro.beans.CandidateType();
420                                 type.setName(c.getIdentifierType().getName());
421                                 can.setIdentifierType(type);
422                                 can.setIdentifiers(c.getIdentifiers());
423                                 can.setCloudOwner(c.getCloudOwner());
424                                 cans.add(can);
425                         }
426                         demand.setExcludedCandidates(cans);
427                 }
428                 //TODO support existing candidates
429         }
430
431         /**
432          * Processes the license solutions and sets to the corresponding generic vnf
433          *
434          */
435         private void processLicenseSolution(ServiceInstance serviceInstance, JSONArray licenseSolutions){
436                 List<GenericVnf> vnfs = serviceInstance.getVnfs();
437
438                 log.debug("Processing the license solution");
439                 for(int i = 0; i < licenseSolutions.length(); i++){
440                         JSONObject licenseSolution = licenseSolutions.getJSONObject(i);
441                         for(GenericVnf vnf:vnfs){
442                                 if(licenseSolution.getString(SERVICE_RESOURCE_ID).equals(vnf.getVnfId())){
443                                         License license = new License();
444                                         JSONArray entitlementPools = licenseSolution.getJSONArray("entitlementPoolUUID");
445                                         List<String> entitlementPoolsList = jsonUtils.StringArrayToList(entitlementPools);
446                                         license.setEntitlementPoolUuids(entitlementPoolsList);
447                                         JSONArray licenseKeys = licenseSolution.getJSONArray("licenseKeyGroupUUID");
448                                         List<String> licenseKeysList = jsonUtils.StringArrayToList(licenseKeys);
449                                         license.setLicenseKeyGroupUuids(licenseKeysList);
450
451                                         vnf.setLicense(license);
452                                 }
453                         }
454                 }
455         }
456
457         /**
458          * Processes a placement solution list then correlates and sets each placement solution
459          * to its corresponding resource
460          *
461          */
462         private void processPlacementSolution(ServiceInstance serviceInstance, JSONArray placements, int i){
463                 List<VpnBondingLink> links = serviceInstance.getVpnBondingLinks();
464                 List<AllottedResource> allottes = serviceInstance.getAllottedResources();
465                 List<GenericVnf> vnfs = serviceInstance.getVnfs();
466
467                 log.debug("Processing placement solution " + i+1);
468                 for(int p = 0; p < placements.length(); p++){
469                         JSONObject placement = placements.getJSONObject(p);
470                         SolutionInfo solutionInfo = new SolutionInfo();
471                         solutionInfo.setSolutionId(i + 1);
472                         search: {
473                                 for(VpnBondingLink vbl:links){
474                                         List<ServiceProxy> proxies = vbl.getServiceProxies();
475                                         for(ServiceProxy sp:proxies){
476                                                 if(placement.getString(SERVICE_RESOURCE_ID).equals(sp.getId())){
477                                                         if(i > 0){
478                                                                 if(p % 2 == 0){
479                                                                         VpnBondingLink vblNew = (VpnBondingLink) SerializationUtils.clone(vbl);
480                                                                         vblNew.setVpnBondingLinkId(UUID.randomUUID().toString());
481                                                                         links.add(vblNew);
482                                                                 }
483                                                                 links.get(links.size() - 1).getServiceProxy(sp.getId()).setServiceInstance(setSolution(solutionInfo, placement));
484                                                         }else{
485                                                                 sp.setServiceInstance(setSolution(solutionInfo, placement));
486                                                         }
487                                                         break search;
488                                                 }
489                                         }
490                                 }
491                                 for(AllottedResource ar:allottes){
492                                         if(placement.getString(SERVICE_RESOURCE_ID).equals(ar.getId())){
493                                                 ar.setParentServiceInstance(setSolution(solutionInfo, placement));
494                                                 break search;
495                                         }
496                                 }
497                                 for(GenericVnf vnf:vnfs){
498                                         if(placement.getString(SERVICE_RESOURCE_ID).equals(vnf.getVnfId())){
499                                                 ServiceInstance si = setSolution(solutionInfo, placement);
500                                                 serviceInstance.setSolutionInfo(si.getSolutionInfo());
501                                                 serviceInstance.getVnfs().add(si.getVnfs().get(0));
502                                                 break search;
503                                         }
504                                 }
505                         }
506                 }
507         }
508
509
510         /**
511          * Creates and sets necessary pojos with placement solution data for a given demand
512          *
513          */
514         private ServiceInstance setSolution(SolutionInfo solutionInfo, JSONObject placement){
515                 log.debug("Mapping placement solution");
516                 String invalidMessage = "Sniro Managers Response contains invalid: ";
517
518                 JSONObject solution = placement.getJSONObject("solution");
519                 String identifierType = solution.getString(IDENTIFIER_TYPE);
520                 List<String> identifiersList = jsonUtils.StringArrayToList(solution.getJSONArray("identifiers").toString());
521                 String identifierValue = identifiersList.get(0);
522
523                 JSONArray assignments = placement.getJSONArray("assignmentInfo");
524                 Map<String, String> assignmentsMap = jsonUtils.entryArrayToMap(assignments.toString(), "key", "value");
525                 solutionInfo.setRehome(Boolean.parseBoolean(assignmentsMap.get("isRehome")));
526                 String type = placement.getString(INVENTORY_TYPE);
527
528                 ServiceInstance si = new ServiceInstance();
529                 CloudRegion cloud = setCloud(assignmentsMap);
530                 if(type.equals("service")){
531                         if(identifierType.equals(CandidateType.SERVICE_INSTANCE_ID.toString())){
532                                 solutionInfo.setHomed(true);
533                                 si.setServiceInstanceId(identifierValue);
534                                 si.setOrchestrationStatus(OrchestrationStatus.CREATED);
535                                 cloud.setLcpCloudRegionId(assignmentsMap.get("cloudRegionId"));
536                                 if(assignmentsMap.containsKey("vnfHostName")){
537                                         log.debug("Resources has been homed to a vnf");
538                                         GenericVnf vnf = setVnf(assignmentsMap);
539                                         vnf.setCloudRegion(cloud);
540                                         si.getVnfs().add(vnf);
541
542                                 }else if(assignmentsMap.containsKey("primaryPnfName")){
543                                         log.debug("Resources has been homed to a pnf");
544                                         Pnf priPnf = setPnf(assignmentsMap, "primary");
545                                         priPnf.setCloudRegion(cloud);
546                                         si.getPnfs().add(priPnf);
547                                         if(assignmentsMap.containsKey("secondaryPnfName")){
548                                                 Pnf secPnf = setPnf(assignmentsMap, "secondary");
549                                                 secPnf.setCloudRegion(cloud);
550                                                 si.getPnfs().add(secPnf);
551                                         }
552                                 }
553                         }else{
554                                 log.debug(invalidMessage + IDENTIFIER_TYPE);
555                                 throw new BpmnError(UNPROCESSABLE, invalidMessage + IDENTIFIER_TYPE);
556                         }
557                 }else if(type.equals("cloud")){
558                         if(identifierType.equals(CandidateType.CLOUD_REGION_ID.toString())){
559                                 log.debug("Resources has been homed to a cloud region");
560                                 cloud.setLcpCloudRegionId(identifierValue);
561                                 solutionInfo.setHomed(false);
562                                 solutionInfo.setTargetedCloudRegion(cloud);
563                                 si.setOrchestrationStatus(OrchestrationStatus.PRECREATED);
564                         }else{
565                                 log.debug(invalidMessage + IDENTIFIER_TYPE);
566                                 throw new BpmnError(UNPROCESSABLE, invalidMessage + IDENTIFIER_TYPE);
567                         }
568                 }else{
569                         log.debug(invalidMessage + INVENTORY_TYPE);
570                         throw new BpmnError(UNPROCESSABLE, invalidMessage + INVENTORY_TYPE);
571                 }
572                 si.setSolutionInfo(solutionInfo);
573                 return si;
574         }
575
576         /**
577          * Sets the cloud data to a cloud region object
578          *
579          */
580         private CloudRegion setCloud(Map<String, String> assignmentsMap){
581                 CloudRegion cloud = new CloudRegion();
582                 cloud.setCloudOwner(assignmentsMap.get("cloudOwner"));
583                 cloud.setCloudRegionVersion(assignmentsMap.get("aicVersion"));
584                 cloud.setComplex(assignmentsMap.get("aicClli"));
585                 return cloud;
586         }
587
588         /**
589          * Sets the vnf data to a generic vnf object
590          *
591          */
592         private GenericVnf setVnf(Map<String, String> assignmentsMap){
593                 GenericVnf vnf = new GenericVnf();
594                 vnf.setOrchestrationStatus(OrchestrationStatus.CREATED);
595                 vnf.setVnfName(assignmentsMap.get("vnfHostName"));
596                 vnf.setVnfId(assignmentsMap.get("vnfId"));
597                 return vnf;
598         }
599
600         /**
601          * Sets the pnf data to a pnf object
602          *
603          */
604         private Pnf setPnf(Map<String, String> assignmentsMap, String role){
605                 Pnf pnf = new Pnf();
606                 pnf.setRole(role);
607                 pnf.setOrchestrationStatus(OrchestrationStatus.CREATED);
608                 pnf.setPnfName(assignmentsMap.get(role + "PnfName"));
609                 return pnf;
610         }
611
612
613
614 }