Supports new aai changes.
[policy/models.git] / models-interactions / model-actors / actor.so / src / main / java / org / onap / policy / controlloop / actor / so / SoActorServiceProvider.java
1 /*
2  * ============LICENSE_START=======================================================
3  * SOActorServiceProvider
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.controlloop.actor.so;
23
24 import com.google.common.collect.ImmutableList;
25 import com.google.common.collect.ImmutableMap;
26 import com.google.gson.reflect.TypeToken;
27 import java.lang.reflect.Type;
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.Map;
31 import org.onap.aai.domain.yang.CloudRegion;
32 import org.onap.aai.domain.yang.GenericVnf;
33 import org.onap.aai.domain.yang.ServiceInstance;
34 import org.onap.aai.domain.yang.Tenant;
35 import org.onap.policy.aai.AaiCqResponse;
36 import org.onap.policy.aai.AaiNqExtraProperty;
37 import org.onap.policy.aai.AaiNqInventoryResponseItem;
38 import org.onap.policy.aai.AaiNqResponseWrapper;
39 import org.onap.policy.controlloop.ControlLoopOperation;
40 import org.onap.policy.controlloop.VirtualControlLoopEvent;
41 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
42 import org.onap.policy.controlloop.policy.Policy;
43 import org.onap.policy.so.SoCloudConfiguration;
44 import org.onap.policy.so.SoManager;
45 import org.onap.policy.so.SoModelInfo;
46 import org.onap.policy.so.SoOperationType;
47 import org.onap.policy.so.SoRelatedInstance;
48 import org.onap.policy.so.SoRelatedInstanceListElement;
49 import org.onap.policy.so.SoRequest;
50 import org.onap.policy.so.SoRequestDetails;
51 import org.onap.policy.so.SoRequestInfo;
52 import org.onap.policy.so.SoRequestParameters;
53 import org.onap.policy.so.util.Serialization;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57 public class SoActorServiceProvider implements Actor {
58     private static final Logger logger = LoggerFactory.getLogger(SoActorServiceProvider.class);
59
60     // Strings for SO Actor
61     private static final String SO_ACTOR = "SO";
62
63     // Strings for targets
64     private static final String TARGET_VFC = "VFC";
65
66     // Strings for recipes
67     private static final String RECIPE_VF_MODULE_CREATE = "VF Module Create";
68     private static final String RECIPE_VF_MODULE_DELETE = "VF Module Delete";
69
70     private static final ImmutableList<String> recipes =
71             ImmutableList.of(RECIPE_VF_MODULE_CREATE, RECIPE_VF_MODULE_DELETE);
72     private static final ImmutableMap<String, List<String>> targets =
73             new ImmutableMap.Builder<String, List<String>>().put(RECIPE_VF_MODULE_CREATE, ImmutableList.of(TARGET_VFC))
74                     .put(RECIPE_VF_MODULE_DELETE, ImmutableList.of(TARGET_VFC)).build();
75
76     // name of request parameters within policy payload
77     public static final String REQ_PARAM_NM = "requestParameters";
78
79     // name of configuration parameters within policy payload
80     public static final String CONFIG_PARAM_NM = "configurationParameters";
81
82     private static final String MODEL_NAME_PROPERTY_KEY = "model-ver.model-name";
83     private static final String MODEL_VERSION_PROPERTY_KEY = "model-ver.model-version";
84     private static final String MODEL_VERSION_ID_PROPERTY_KEY = "model-ver.model-version-id";
85
86     // used to decode configuration parameters via gson
87     private static final Type CONFIG_TYPE = new TypeToken<List<Map<String, String>>>() {}.getType();
88
89     // Static variables required to hold the IDs of the last service item, VNF item and VF Module.
90     // Note that in
91     // a multithreaded deployment this WILL break
92     private static String lastVNFItemVnfId;
93     private static String lastServiceItemServiceInstanceId;
94     private static String lastVfModuleItemVfModuleInstanceId;
95
96     @Override
97     public String actor() {
98         return SO_ACTOR;
99     }
100
101     @Override
102     public List<String> recipes() {
103         return ImmutableList.copyOf(recipes);
104     }
105
106     @Override
107     public List<String> recipeTargets(String recipe) {
108         return ImmutableList.copyOf(targets.getOrDefault(recipe, Collections.emptyList()));
109     }
110
111     @Override
112     public List<String> recipePayloads(String recipe) {
113         return Collections.emptyList();
114     }
115
116     /**
117      * Constructs a SO request conforming to the lcm API. The actual request is constructed and then placed in a wrapper
118      * object used to send through DMAAP.
119      *
120      * @param onset the event that is reporting the alert for policy to perform an action
121      * @param operation the control loop operation specifying the actor, operation, target, etc.
122      * @param policy the policy the was specified from the yaml generated by CLAMP or through the Policy GUI/API
123      * @param aaiResponseWrapper wrapper for AAI vserver named-query response
124      * @return a SO request conforming to the lcm API using the DMAAP wrapper
125      */
126     public SoRequest constructRequest(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy,
127             AaiNqResponseWrapper aaiResponseWrapper) {
128         if (!SO_ACTOR.equals(policy.getActor()) || !recipes().contains(policy.getRecipe())) {
129             return null;
130         }
131
132         // A&AI named query should have been performed by now. If not, return null
133         if (aaiResponseWrapper == null) {
134             return null;
135         }
136
137         AaiNqInventoryResponseItem vnfItem;
138         AaiNqInventoryResponseItem vnfServiceItem;
139         AaiNqInventoryResponseItem tenantItem;
140
141         // Extract the items we're interested in from the response
142         try {
143             vnfItem = aaiResponseWrapper.getAaiNqResponse().getInventoryResponseItems().get(0).getItems()
144                     .getInventoryResponseItems().get(0);
145         } catch (Exception e) {
146             logger.error("VNF Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiResponseWrapper),
147                     e);
148             return null;
149         }
150
151         try {
152             vnfServiceItem = vnfItem.getItems().getInventoryResponseItems().get(0);
153         } catch (Exception e) {
154             logger.error("VNF Service Item not found in AAI response {}",
155                     Serialization.gsonPretty.toJson(aaiResponseWrapper), e);
156             return null;
157         }
158
159         try {
160             tenantItem = aaiResponseWrapper.getAaiNqResponse().getInventoryResponseItems().get(0).getItems()
161                     .getInventoryResponseItems().get(1);
162         } catch (Exception e) {
163             logger.error("Tenant Item not found in AAI response {}",
164                     Serialization.gsonPretty.toJson(aaiResponseWrapper), e);
165             return null;
166         }
167
168         // Find the index for base vf module and non-base vf module
169         AaiNqInventoryResponseItem baseItem = findVfModule(aaiResponseWrapper, true);
170
171         SoModelInfo soModelInfo = prepareSoModelInfo(policy);
172
173         // Report the error if either base vf module or non-base vf module is not found
174         if (baseItem == null || soModelInfo == null) {
175             logger.error("Either base or non-base vf module is not found from AAI response.");
176             return null;
177         }
178
179         // Construct SO Request for a policy's recipe
180         if (RECIPE_VF_MODULE_CREATE.equals(policy.getRecipe())) {
181             return constructCreateRequest(aaiResponseWrapper, policy, tenantItem, vnfItem, vnfServiceItem, soModelInfo);
182         } else if (RECIPE_VF_MODULE_DELETE.equals(policy.getRecipe())) {
183             return constructDeleteRequest(tenantItem, vnfItem, vnfServiceItem, soModelInfo, policy);
184         } else {
185             return null;
186         }
187     }
188
189     private SoModelInfo prepareSoModelInfo(Policy policy) {
190
191         SoModelInfo soModelInfo = new SoModelInfo();
192         if ((policy.getTarget() != null && (policy.getTarget().getModelCustomizationId() != null))
193                 && (policy.getTarget().getModelInvariantId() != null) && (policy.getTarget().getModelName() != null)
194                 && (policy.getTarget().getModelVersion() != null) && (policy.getTarget().getModelVersionId() != null)) {
195
196             soModelInfo.setModelCustomizationId(policy.getTarget().getModelCustomizationId());
197             soModelInfo.setModelInvariantId(policy.getTarget().getModelInvariantId());
198             soModelInfo.setModelName(policy.getTarget().getModelName());
199             soModelInfo.setModelVersion(policy.getTarget().getModelVersion());
200             soModelInfo.setModelVersionId(policy.getTarget().getModelVersionId());
201             return soModelInfo;
202         } else {
203             return null;
204         }
205     }
206
207     /**
208      * Construct SO request to create vf-module.
209      *
210      * @param aaiResponseWrapper the AAI response containing the VF modules
211      * @param policy the policy
212      * @param tenantItem tenant item from A&AI named-query response
213      * @param vnfItem vnf item from A&AI named-query response
214      * @param vnfServiceItem vnf service item from A&AI named-query response
215      * @param vfModuleItem vf module item from A&AI named-query response
216      * @return SO create vf-module request
217      */
218     private SoRequest constructCreateRequest(AaiNqResponseWrapper aaiResponseWrapper, Policy policy,
219             AaiNqInventoryResponseItem tenantItem, AaiNqInventoryResponseItem vnfItem,
220             AaiNqInventoryResponseItem vnfServiceItem, SoModelInfo vfModuleItem) {
221         SoRequest request = new SoRequest();
222         request.setOperationType(SoOperationType.SCALE_OUT);
223         //
224         //
225         // Do NOT send So the requestId, they do not support this field
226         //
227         request.setRequestDetails(new SoRequestDetails());
228         request.getRequestDetails().setRequestParameters(new SoRequestParameters());
229         request.getRequestDetails().getRequestParameters().setUserParams(null);
230
231         // cloudConfiguration
232         request.getRequestDetails().setCloudConfiguration(constructCloudConfiguration(tenantItem));
233         // modelInfo
234         request.getRequestDetails().setModelInfo(vfModuleItem);
235
236         // requestInfo
237         request.getRequestDetails().setRequestInfo(constructRequestInfo());
238         String vfModuleName = aaiResponseWrapper.genVfModuleName();
239         request.getRequestDetails().getRequestInfo().setInstanceName(vfModuleName);
240
241         // relatedInstanceList
242         SoRelatedInstanceListElement relatedInstanceListElement1 = new SoRelatedInstanceListElement();
243         SoRelatedInstanceListElement relatedInstanceListElement2 = new SoRelatedInstanceListElement();
244         relatedInstanceListElement1.setRelatedInstance(new SoRelatedInstance());
245         relatedInstanceListElement2.setRelatedInstance(new SoRelatedInstance());
246
247         // Service Item
248         relatedInstanceListElement1.getRelatedInstance()
249                 .setInstanceId(vnfServiceItem.getServiceInstance().getServiceInstanceId());
250         relatedInstanceListElement1.getRelatedInstance().setModelInfo(new SoModelInfo());
251         relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelType("service");
252         relatedInstanceListElement1.getRelatedInstance().getModelInfo()
253                 .setModelInvariantId(vnfServiceItem.getServiceInstance().getModelInvariantId());
254         for (AaiNqExtraProperty prop : vnfServiceItem.getExtraProperties().getExtraProperty()) {
255             if (prop.getPropertyName().equals(MODEL_NAME_PROPERTY_KEY)) {
256                 relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelName(prop.getPropertyValue());
257             } else if (prop.getPropertyName().equals(MODEL_VERSION_PROPERTY_KEY)) {
258                 relatedInstanceListElement1.getRelatedInstance().getModelInfo()
259                         .setModelVersion(prop.getPropertyValue());
260             } else if (prop.getPropertyName().equals(MODEL_VERSION_ID_PROPERTY_KEY)) {
261                 relatedInstanceListElement1.getRelatedInstance().getModelInfo()
262                         .setModelVersionId(prop.getPropertyValue());
263             }
264         }
265
266         // VNF Item
267         relatedInstanceListElement2.getRelatedInstance().setInstanceId(vnfItem.getGenericVnf().getVnfId());
268         relatedInstanceListElement2.getRelatedInstance().setModelInfo(new SoModelInfo());
269         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelType("vnf");
270         relatedInstanceListElement2.getRelatedInstance().getModelInfo()
271                 .setModelInvariantId(vnfItem.getGenericVnf().getModelInvariantId());
272         for (AaiNqExtraProperty prop : vnfItem.getExtraProperties().getExtraProperty()) {
273             if (prop.getPropertyName().equals(MODEL_NAME_PROPERTY_KEY)) {
274                 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelName(prop.getPropertyValue());
275             } else if (prop.getPropertyName().equals(MODEL_VERSION_PROPERTY_KEY)) {
276                 relatedInstanceListElement2.getRelatedInstance().getModelInfo()
277                         .setModelVersion(prop.getPropertyValue());
278             } else if (prop.getPropertyName().equals(MODEL_VERSION_ID_PROPERTY_KEY)) {
279                 relatedInstanceListElement2.getRelatedInstance().getModelInfo()
280                         .setModelVersionId(prop.getPropertyValue());
281             }
282         }
283
284         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelCustomizationName(vnfItem
285                 .getGenericVnf().getVnfType().substring(vnfItem.getGenericVnf().getVnfType().lastIndexOf('/') + 1));
286         relatedInstanceListElement2.getRelatedInstance().getModelInfo()
287                 .setModelCustomizationId(vnfItem.getGenericVnf().getModelCustomizationId());
288
289         // Insert the Service Item and VNF Item
290         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement1);
291         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement2);
292
293         // Request Parameters
294         buildRequestParameters(policy, request.getRequestDetails());
295
296         // Configuration Parameters
297         buildConfigurationParameters(policy, request.getRequestDetails());
298         // Save the instance IDs for the VNF and service to static fields
299         // vfModuleId is not required for the create vf-module
300         preserveInstanceIds(vnfItem.getGenericVnf().getVnfId(),
301                 vnfServiceItem.getServiceInstance().getServiceInstanceId(), null);
302         if (logger.isDebugEnabled()) {
303             logger.debug("Constructed SO request: {}", Serialization.gsonPretty.toJson(request));
304         }
305         return request;
306     }
307
308     /**
309      * Construct SO request to delete vf-module.
310      *
311      * @param tenantItem tenant item from A&AI named-query response
312      * @param vnfItem vnf item from A&AI named-query response
313      * @param vnfServiceItem vnf service item from A&AI named-query response
314      * @param vfModuleItem vf module item from A&AI named-query response
315      * @return SO delete vf-module request
316      */
317     private SoRequest constructDeleteRequest(AaiNqInventoryResponseItem tenantItem, AaiNqInventoryResponseItem vnfItem,
318             AaiNqInventoryResponseItem vnfServiceItem, SoModelInfo vfModuleItem, Policy policy) {
319         SoRequest request = new SoRequest();
320         request.setOperationType(SoOperationType.DELETE_VF_MODULE);
321         request.setRequestDetails(new SoRequestDetails());
322         request.getRequestDetails().setRelatedInstanceList(null);
323         request.getRequestDetails().setConfigurationParameters(null);
324
325         // cloudConfiguration
326         request.getRequestDetails().setCloudConfiguration(constructCloudConfiguration(tenantItem));
327         // modelInfo
328         request.getRequestDetails().setModelInfo(prepareSoModelInfo(policy));
329         // requestInfo
330         request.getRequestDetails().setRequestInfo(constructRequestInfo());
331         // Save the instance IDs for the VNF, service and vfModule to static fields
332         preserveInstanceIds(vnfItem.getGenericVnf().getVnfId(),
333                 vnfServiceItem.getServiceInstance().getServiceInstanceId(), null);
334
335         if (logger.isDebugEnabled()) {
336             logger.debug("Constructed SO request: {}", Serialization.gsonPretty.toJson(request));
337         }
338         return request;
339     }
340
341     /**
342      * Construct requestInfo for the SO requestDetails.
343      *
344      * @return SO request information
345      */
346     private SoRequestInfo constructRequestInfo() {
347         SoRequestInfo soRequestInfo = new SoRequestInfo();
348         soRequestInfo.setSource("POLICY");
349         soRequestInfo.setSuppressRollback(false);
350         soRequestInfo.setRequestorId("policy");
351         return soRequestInfo;
352     }
353
354     /**
355      * Construct cloudConfiguration for the SO requestDetails.
356      *
357      * @param tenantItem tenant item from A&AI named-query response
358      * @return SO cloud configuration
359      */
360     private SoCloudConfiguration constructCloudConfiguration(AaiNqInventoryResponseItem tenantItem) {
361         SoCloudConfiguration cloudConfiguration = new SoCloudConfiguration();
362         cloudConfiguration.setTenantId(tenantItem.getTenant().getTenantId());
363         cloudConfiguration.setLcpCloudRegionId(
364                 tenantItem.getItems().getInventoryResponseItems().get(0).getCloudRegion().getCloudRegionId());
365         return cloudConfiguration;
366     }
367
368     /**
369      * This method is needed to get the serviceInstanceId and vnfInstanceId which is used in the asyncSORestCall.
370      *
371      * @param requestId the request Id
372      * @param callback callback method
373      * @param request the request
374      * @param url SO REST URL
375      * @param user username
376      * @param password password
377      */
378     public static void sendRequest(String requestId, SoManager.SoCallback callback, Object request, String url,
379             String user, String password) {
380         SoManager soManager = new SoManager(url, user, password);
381         soManager.asyncSoRestCall(requestId, callback, lastServiceItemServiceInstanceId, lastVNFItemVnfId,
382                 lastVfModuleItemVfModuleInstanceId, (SoRequest) request);
383     }
384
385     /**
386      * Find the base or non base VF module item in an AAI response. If there is more than one item, then the <i>last</i>
387      * item is returned
388      *
389      * @param aaiResponseWrapper the AAI response containing the VF modules
390      * @param baseFlag true if we are searching for the base, false if we are searching for the non base
391      * @return the base or non base VF module item or null if the module was not found
392      */
393     private AaiNqInventoryResponseItem findVfModule(AaiNqResponseWrapper aaiResponseWrapper, boolean baseFlag) {
394         List<AaiNqInventoryResponseItem> lst = aaiResponseWrapper.getVfModuleItems(baseFlag);
395         return (lst.isEmpty() ? null : lst.get(lst.size() - 1));
396     }
397
398     /**
399      * Builds the request parameters from the policy payload.
400      *
401      * @param policy the policy
402      * @param request request into which to stick the request parameters
403      */
404     private void buildRequestParameters(Policy policy, SoRequestDetails request) {
405         // assume null until proven otherwise
406         request.setRequestParameters(null);
407
408         if (policy.getPayload() == null) {
409             return;
410         }
411
412         String json = policy.getPayload().get(REQ_PARAM_NM);
413         if (json == null) {
414             return;
415         }
416
417         request.setRequestParameters(Serialization.gsonPretty.fromJson(json, SoRequestParameters.class));
418     }
419
420     /**
421      * Builds the configuration parameters from the policy payload.
422      *
423      * @param policy the policy
424      * @param request request into which to stick the configuration parameters
425      */
426     private void buildConfigurationParameters(Policy policy, SoRequestDetails request) {
427         // assume null until proven otherwise
428         request.setConfigurationParameters(null);
429
430         if (policy.getPayload() == null) {
431             return;
432         }
433
434         String json = policy.getPayload().get(CONFIG_PARAM_NM);
435         if (json == null) {
436             return;
437         }
438
439         request.setConfigurationParameters(Serialization.gsonPretty.fromJson(json, CONFIG_TYPE));
440     }
441
442     /**
443      * This method is called to remember the last service instance ID, VNF Item VNF ID and vf module ID. Note these
444      * fields are static, beware for multithreaded deployments
445      *
446      * @param vnfInstanceId update the last VNF instance ID to this value
447      * @param serviceInstanceId update the last service instance ID to this value
448      * @param vfModuleId update the vfModule instance ID to this value
449      */
450     private static void preserveInstanceIds(final String vnfInstanceId, final String serviceInstanceId,
451             final String vfModuleId) {
452         lastVNFItemVnfId = vnfInstanceId;
453         lastServiceItemServiceInstanceId = serviceInstanceId;
454         lastVfModuleItemVfModuleInstanceId = vfModuleId;
455     }
456
457     /**
458      * Constructs a SO request conforming to the lcm API. The actual request is constructed and then placed in a wrapper
459      * object used to send through DMAAP.
460      *
461      * @param onset the event that is reporting the alert for policy to perform an action
462      * @param operation the control loop operation specifying the actor, operation, target, etc.
463      * @param policy the policy the was specified from the yaml generated by CLAMP or through the Policy GUI/API
464      * @param aaiCqResponse response from A&AI custom query
465      * @return a SO request conforming to the lcm API using the DMAAP wrapper
466      */
467     public SoRequest constructRequestCq(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy,
468             AaiCqResponse aaiCqResponse) {
469         if (!SO_ACTOR.equals(policy.getActor()) || !recipes().contains(policy.getRecipe())) {
470             return null;
471         }
472
473         // A&AI named query should have been performed by now. If not, return null
474         if (aaiCqResponse == null) {
475             return null;
476         }
477
478         SoModelInfo soModelInfo = prepareSoModelInfo(policy);
479
480         // Report the error vf module is not found
481         if (soModelInfo == null) {
482             logger.error("vf module is not found.");
483             return null;
484         }
485
486         GenericVnf vnfItem;
487         ServiceInstance vnfServiceItem;
488         Tenant tenantItem;
489         CloudRegion cloudRegionItem;
490
491         // Extract the items we're interested in from the response
492         try {
493             vnfItem = aaiCqResponse.getGenericVnfByVfModuleModelInvariantId(soModelInfo.getModelInvariantId());
494             //Report VNF not found
495             if (vnfItem == null) {
496                 logger.error("Generic Vnf is not found.");
497                 return null;
498             }
499         } catch (Exception e) {
500             logger.error("VNF Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiCqResponse), e);
501             return null;
502         }
503
504         try {
505             vnfServiceItem = aaiCqResponse.getServiceInstance();
506         } catch (Exception e) {
507             logger.error("VNF Service Item not found in AAI response {}",
508                     Serialization.gsonPretty.toJson(aaiCqResponse), e);
509             return null;
510         }
511
512         try {
513             tenantItem = aaiCqResponse.getDefaultTenant();
514         } catch (Exception e) {
515             logger.error("Tenant Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiCqResponse), e);
516             return null;
517         }
518
519         try {
520             cloudRegionItem = aaiCqResponse.getDefaultCloudRegion();
521         } catch (Exception e) {
522             logger.error("Tenant Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiCqResponse), e);
523             return null;
524         }
525
526
527
528         // Construct SO Request for a policy's recipe
529         if (RECIPE_VF_MODULE_CREATE.equals(policy.getRecipe())) {
530             return constructCreateRequestCq(aaiCqResponse, policy, tenantItem, vnfItem, vnfServiceItem, soModelInfo,
531                     cloudRegionItem);
532         } else if (RECIPE_VF_MODULE_DELETE.equals(policy.getRecipe())) {
533             return constructDeleteRequestCq(tenantItem, vnfItem, vnfServiceItem, soModelInfo, policy, cloudRegionItem);
534         } else {
535             return null;
536         }
537     }
538
539     /**
540      * Construct the So request, based on Custom Query response from A&AI.
541      *
542      * @param aaiCqResponse Custom query response from A&AI
543      * @param policy policy information
544      * @param tenantItem Tenant from CQ response
545      * @param vnfItem Generic VNF from CQ response
546      * @param vnfServiceItem Service Instance from CQ response
547      * @param vfModuleItem VF Module from CustomQuery response
548      * @param cloudRegionItem Cloud Region from Custom query response
549      * @return SoRequest well formed So Request
550      */
551     private SoRequest constructCreateRequestCq(AaiCqResponse aaiCqResponse, Policy policy, Tenant tenantItem,
552             GenericVnf vnfItem, ServiceInstance vnfServiceItem, SoModelInfo vfModuleItem, CloudRegion cloudRegionItem) {
553         SoRequest request = new SoRequest();
554         request.setOperationType(SoOperationType.SCALE_OUT);
555         //
556         //
557         // Do NOT send So the requestId, they do not support this field
558         //
559         request.setRequestDetails(new SoRequestDetails());
560         request.getRequestDetails().setRequestParameters(new SoRequestParameters());
561         request.getRequestDetails().getRequestParameters().setUserParams(null);
562
563         // cloudConfiguration
564         request.getRequestDetails().setCloudConfiguration(constructCloudConfigurationCq(tenantItem, cloudRegionItem));
565         // modelInfo
566         request.getRequestDetails().setModelInfo(vfModuleItem);
567
568
569         // requestInfo
570         request.getRequestDetails().setRequestInfo(constructRequestInfo());
571         request.getRequestDetails().getRequestInfo().setInstanceName("vfModuleName");
572
573         // relatedInstanceList
574         SoRelatedInstanceListElement relatedInstanceListElement1 = new SoRelatedInstanceListElement();
575         SoRelatedInstanceListElement relatedInstanceListElement2 = new SoRelatedInstanceListElement();
576         relatedInstanceListElement1.setRelatedInstance(new SoRelatedInstance());
577         relatedInstanceListElement2.setRelatedInstance(new SoRelatedInstance());
578
579         // Service Item
580         relatedInstanceListElement1.getRelatedInstance().setInstanceId(vnfServiceItem.getServiceInstanceId());
581         relatedInstanceListElement1.getRelatedInstance().setModelInfo(new SoModelInfo());
582         relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelType("service");
583         relatedInstanceListElement1.getRelatedInstance().getModelInfo()
584                 .setModelInvariantId(vnfServiceItem.getModelInvariantId());
585         relatedInstanceListElement1.getRelatedInstance().getModelInfo()
586                 .setModelVersionId(vnfServiceItem.getModelVersionId());
587         relatedInstanceListElement1.getRelatedInstance().getModelInfo()
588                 .setModelName(aaiCqResponse.getModelVerByVersionId(vnfServiceItem.getModelVersionId()).getModelName());
589         relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelVersion(
590                 aaiCqResponse.getModelVerByVersionId(vnfServiceItem.getModelVersionId()).getModelVersion());
591
592
593         // VNF Item
594         relatedInstanceListElement2.getRelatedInstance().setInstanceId(vnfItem.getVnfId());
595         relatedInstanceListElement2.getRelatedInstance().setModelInfo(new SoModelInfo());
596         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelType("vnf");
597         relatedInstanceListElement2.getRelatedInstance().getModelInfo()
598                 .setModelInvariantId(vnfItem.getModelInvariantId());
599         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelVersionId(vnfItem.getModelVersionId());
600
601         relatedInstanceListElement2.getRelatedInstance().getModelInfo()
602                 .setModelName(aaiCqResponse.getModelVerByVersionId(vnfItem.getModelVersionId()).getModelName());
603         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelVersion(
604                 aaiCqResponse.getModelVerByVersionId(vnfServiceItem.getModelVersionId()).getModelVersion());
605
606
607         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelCustomizationName(
608                 vnfItem.getVnfType().substring(vnfItem.getVnfType().lastIndexOf('/') + 1));
609         relatedInstanceListElement2.getRelatedInstance().getModelInfo()
610                 .setModelCustomizationId(vnfItem.getModelCustomizationId());
611
612
613         // Insert the Service Item and VNF Item
614         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement1);
615         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement2);
616
617         // Request Parameters
618         buildRequestParameters(policy, request.getRequestDetails());
619
620         // Configuration Parameters
621         buildConfigurationParameters(policy, request.getRequestDetails());
622         // Save the instance IDs for the VNF and service to static fields
623         // vfModuleId is not required for the create vf-module
624         preserveInstanceIds(vnfItem.getVnfId(), vnfServiceItem.getServiceInstanceId(), null);
625         if (logger.isDebugEnabled()) {
626             logger.debug("Constructed SO request: {}", Serialization.gsonPretty.toJson(request));
627         }
628         return request;
629     }
630
631     /**
632      * constructs delete request for So.
633      *
634      * @param tenantItem Tenant from A&AI CQ request
635      * @param vnfItem Generic VNF from A&AI CQ request
636      * @param vnfServiceItem ServiceInstance from A&AI CQ request
637      * @param vfModuleItem VFModule from A&AI CQ request
638      * @param policy policy information
639      * @param cloudRegionItem CloudRegion from A&AI CQ request
640      * @return SoRequest deleted
641      */
642     private SoRequest constructDeleteRequestCq(Tenant tenantItem, GenericVnf vnfItem, ServiceInstance vnfServiceItem,
643             SoModelInfo vfModuleItem, Policy policy, CloudRegion cloudRegionItem) {
644         SoRequest request = new SoRequest();
645         request.setOperationType(SoOperationType.DELETE_VF_MODULE);
646         request.setRequestDetails(new SoRequestDetails());
647         request.getRequestDetails().setRelatedInstanceList(null);
648         request.getRequestDetails().setConfigurationParameters(null);
649
650         // cloudConfiguration
651         request.getRequestDetails().setCloudConfiguration(constructCloudConfigurationCq(tenantItem, cloudRegionItem));
652         // modelInfo
653         request.getRequestDetails().setModelInfo(prepareSoModelInfo(policy));
654         // requestInfo
655         request.getRequestDetails().setRequestInfo(constructRequestInfo());
656         // Save the instance IDs for the VNF, service and vfModule to static fields
657         preserveInstanceIds(vnfItem.getVnfId(), vnfServiceItem.getServiceInstanceId(), null);
658
659         if (logger.isDebugEnabled()) {
660             logger.debug("Constructed SO request: {}", Serialization.gsonPretty.toJson(request));
661         }
662         return request;
663     }
664
665
666     /**
667      * Construct cloudConfiguration for the SO requestDetails. Overridden for custom query.
668      *
669      * @param tenantItem tenant item from A&AI named-query response
670      * @return SO cloud configuration
671      */
672     private SoCloudConfiguration constructCloudConfigurationCq(Tenant tenantItem, CloudRegion cloudRegionItem) {
673         SoCloudConfiguration cloudConfiguration = new SoCloudConfiguration();
674         cloudConfiguration.setTenantId(tenantItem.getTenantId());
675         cloudConfiguration.setLcpCloudRegionId(cloudRegionItem.getCloudRegionId());
676         return cloudConfiguration;
677     }
678
679 }