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