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