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