Removing Named Query.
[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.controlloop.ControlLoopOperation;
37 import org.onap.policy.controlloop.VirtualControlLoopEvent;
38 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
39 import org.onap.policy.controlloop.policy.Policy;
40 import org.onap.policy.so.SoCloudConfiguration;
41 import org.onap.policy.so.SoManager;
42 import org.onap.policy.so.SoModelInfo;
43 import org.onap.policy.so.SoOperationType;
44 import org.onap.policy.so.SoRelatedInstance;
45 import org.onap.policy.so.SoRelatedInstanceListElement;
46 import org.onap.policy.so.SoRequest;
47 import org.onap.policy.so.SoRequestDetails;
48 import org.onap.policy.so.SoRequestInfo;
49 import org.onap.policy.so.SoRequestParameters;
50 import org.onap.policy.so.util.Serialization;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 public class SoActorServiceProvider implements Actor {
55     private static final Logger logger = LoggerFactory.getLogger(SoActorServiceProvider.class);
56
57     private static final String TENANT_NOT_FOUND = "Tenant Item not found in AAI response {}";
58     private static final String CONSTRUCTED_SO_MSG = "Constructed SO request: {}";
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     // used to decode configuration parameters via gson
83     private static final Type CONFIG_TYPE = new TypeToken<List<Map<String, String>>>() {}.getType();
84
85     // Static variables required to hold the IDs of the last service item, VNF item and VF Module.
86     // Note that in
87     // a multithreaded deployment this WILL break
88     private static String lastVNFItemVnfId;
89     private static String lastServiceItemServiceInstanceId;
90     private static String lastVfModuleItemVfModuleInstanceId;
91
92     @Override
93     public String actor() {
94         return SO_ACTOR;
95     }
96
97     @Override
98     public List<String> recipes() {
99         return ImmutableList.copyOf(recipes);
100     }
101
102     @Override
103     public List<String> recipeTargets(String recipe) {
104         return ImmutableList.copyOf(targets.getOrDefault(recipe, Collections.emptyList()));
105     }
106
107     @Override
108     public List<String> recipePayloads(String recipe) {
109         return Collections.emptyList();
110     }
111
112     private SoModelInfo prepareSoModelInfo(Policy policy) {
113
114         if (policy.getTarget() == null || policy.getTarget().getModelCustomizationId() == null
115                         || policy.getTarget().getModelInvariantId() == null) {
116             return null;
117         }
118
119         if (policy.getTarget().getModelName() == null || policy.getTarget().getModelVersion() == null
120                         || policy.getTarget().getModelVersionId() == null) {
121             return null;
122         }
123
124         SoModelInfo soModelInfo = new SoModelInfo();
125         soModelInfo.setModelCustomizationId(policy.getTarget().getModelCustomizationId());
126         soModelInfo.setModelInvariantId(policy.getTarget().getModelInvariantId());
127         soModelInfo.setModelName(policy.getTarget().getModelName());
128         soModelInfo.setModelVersion(policy.getTarget().getModelVersion());
129         soModelInfo.setModelVersionId(policy.getTarget().getModelVersionId());
130         soModelInfo.setModelType("vfModule");
131         return soModelInfo;
132     }
133
134     /**
135      * Construct requestInfo for the SO requestDetails.
136      *
137      * @return SO request information
138      */
139     private SoRequestInfo constructRequestInfo() {
140         SoRequestInfo soRequestInfo = new SoRequestInfo();
141         soRequestInfo.setSource("POLICY");
142         soRequestInfo.setSuppressRollback(false);
143         soRequestInfo.setRequestorId("policy");
144         return soRequestInfo;
145     }
146
147     /**
148      * This method is needed to get the serviceInstanceId and vnfInstanceId which is used in the asyncSORestCall.
149      *
150      * @param requestId the request Id
151      * @param callback callback method
152      * @param request the request
153      * @param url SO REST URL
154      * @param user username
155      * @param password password
156      */
157     public static void sendRequest(String requestId, SoManager.SoCallback callback, Object request, String url,
158             String user, String password) {
159         SoManager soManager = new SoManager(url, user, password);
160         soManager.asyncSoRestCall(requestId, callback, lastServiceItemServiceInstanceId, lastVNFItemVnfId,
161                 lastVfModuleItemVfModuleInstanceId, (SoRequest) request);
162     }
163
164
165     /**
166      * Builds the request parameters from the policy payload.
167      *
168      * @param policy the policy
169      * @param request request into which to stick the request parameters
170      */
171     private void buildRequestParameters(Policy policy, SoRequestDetails request) {
172         // assume null until proven otherwise
173         request.setRequestParameters(null);
174
175         if (policy.getPayload() == null) {
176             return;
177         }
178
179         String json = policy.getPayload().get(REQ_PARAM_NM);
180         if (json == null) {
181             return;
182         }
183
184         request.setRequestParameters(Serialization.gsonPretty.fromJson(json, SoRequestParameters.class));
185     }
186
187     /**
188      * Builds the configuration parameters from the policy payload.
189      *
190      * @param policy the policy
191      * @param request request into which to stick the configuration parameters
192      */
193     private void buildConfigurationParameters(Policy policy, SoRequestDetails request) {
194         // assume null until proven otherwise
195         request.setConfigurationParameters(null);
196
197         if (policy.getPayload() == null) {
198             return;
199         }
200
201         String json = policy.getPayload().get(CONFIG_PARAM_NM);
202         if (json == null) {
203             return;
204         }
205
206         request.setConfigurationParameters(Serialization.gsonPretty.fromJson(json, CONFIG_TYPE));
207     }
208
209     /**
210      * This method is called to remember the last service instance ID, VNF Item VNF ID and vf module ID. Note these
211      * fields are static, beware for multithreaded deployments
212      *
213      * @param vnfInstanceId update the last VNF instance ID to this value
214      * @param serviceInstanceId update the last service instance ID to this value
215      * @param vfModuleId update the vfModule instance ID to this value
216      */
217     private static void preserveInstanceIds(final String vnfInstanceId, final String serviceInstanceId,
218             final String vfModuleId) {
219         lastVNFItemVnfId = vnfInstanceId;
220         lastServiceItemServiceInstanceId = serviceInstanceId;
221         lastVfModuleItemVfModuleInstanceId = vfModuleId;
222     }
223
224     /**
225      * Constructs a SO request conforming to the lcm API. The actual request is constructed and then placed in a wrapper
226      * object used to send through DMAAP.
227      *
228      * @param onset the event that is reporting the alert for policy to perform an action
229      * @param operation the control loop operation specifying the actor, operation, target, etc.
230      * @param policy the policy the was specified from the yaml generated by CLAMP or through the Policy GUI/API
231      * @param aaiCqResponse response from A&AI custom query
232      * @return a SO request conforming to the lcm API using the DMAAP wrapper
233      */
234     public SoRequest constructRequestCq(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy,
235             AaiCqResponse aaiCqResponse) {
236         if (!SO_ACTOR.equals(policy.getActor()) || !recipes().contains(policy.getRecipe())) {
237             return null;
238         }
239
240         // A&AI named query should have been performed by now. If not, return null
241         if (aaiCqResponse == null) {
242             return null;
243         }
244
245         SoModelInfo soModelInfo = prepareSoModelInfo(policy);
246
247         // Report the error vf module is not found
248         if (soModelInfo == null) {
249             logger.error("vf module is not found.");
250             return null;
251         }
252
253         GenericVnf vnfItem;
254         ServiceInstance vnfServiceItem;
255         Tenant tenantItem;
256         CloudRegion cloudRegionItem;
257
258         // Extract the items we're interested in from the response
259         try {
260             vnfItem = aaiCqResponse.getGenericVnfByVfModuleModelInvariantId(soModelInfo.getModelInvariantId());
261             //Report VNF not found
262             if (vnfItem == null) {
263                 logger.error("Generic Vnf is not found.");
264                 return null;
265             }
266         } catch (Exception e) {
267             logger.error("VNF Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiCqResponse), e);
268             return null;
269         }
270
271         try {
272             vnfServiceItem = aaiCqResponse.getServiceInstance();
273         } catch (Exception e) {
274             logger.error("VNF Service Item not found in AAI response {}",
275                     Serialization.gsonPretty.toJson(aaiCqResponse), e);
276             return null;
277         }
278
279         try {
280             tenantItem = aaiCqResponse.getDefaultTenant();
281         } catch (Exception e) {
282             logger.error(TENANT_NOT_FOUND, Serialization.gsonPretty.toJson(aaiCqResponse), e);
283             return null;
284         }
285
286         try {
287             cloudRegionItem = aaiCqResponse.getDefaultCloudRegion();
288         } catch (Exception e) {
289             logger.error(TENANT_NOT_FOUND, Serialization.gsonPretty.toJson(aaiCqResponse), e);
290             return null;
291         }
292
293
294
295         // Construct SO Request for a policy's recipe
296         if (RECIPE_VF_MODULE_CREATE.equals(policy.getRecipe())) {
297             return constructCreateRequestCq(aaiCqResponse, policy, tenantItem, vnfItem, vnfServiceItem, soModelInfo,
298                     cloudRegionItem);
299         } else if (RECIPE_VF_MODULE_DELETE.equals(policy.getRecipe())) {
300             return constructDeleteRequestCq(tenantItem, vnfItem, vnfServiceItem, policy, cloudRegionItem);
301         } else {
302             return null;
303         }
304     }
305
306     /**
307      * Construct the So request, based on Custom Query response from A&AI.
308      *
309      * @param aaiCqResponse Custom query response from A&AI
310      * @param policy policy information
311      * @param tenantItem Tenant from CQ response
312      * @param vnfItem Generic VNF from CQ response
313      * @param vnfServiceItem Service Instance from CQ response
314      * @param vfModuleItem VF Module from CustomQuery response
315      * @param cloudRegionItem Cloud Region from Custom query response
316      * @return SoRequest well formed So Request
317      */
318     private SoRequest constructCreateRequestCq(AaiCqResponse aaiCqResponse, Policy policy, Tenant tenantItem,
319             GenericVnf vnfItem, ServiceInstance vnfServiceItem, SoModelInfo vfModuleItem, CloudRegion cloudRegionItem) {
320         SoRequest request = new SoRequest();
321         request.setOperationType(SoOperationType.SCALE_OUT);
322         //
323         //
324         // Do NOT send So the requestId, they do not support this field
325         //
326         request.setRequestDetails(new SoRequestDetails());
327         request.getRequestDetails().setRequestParameters(new SoRequestParameters());
328         request.getRequestDetails().getRequestParameters().setUserParams(null);
329
330         // cloudConfiguration
331         request.getRequestDetails().setCloudConfiguration(constructCloudConfigurationCq(tenantItem, cloudRegionItem));
332         // modelInfo
333         request.getRequestDetails().setModelInfo(vfModuleItem);
334
335
336         // requestInfo
337         request.getRequestDetails().setRequestInfo(constructRequestInfo());
338         request.getRequestDetails().getRequestInfo().setInstanceName("vfModuleName");
339
340         // relatedInstanceList
341         SoRelatedInstanceListElement relatedInstanceListElement1 = new SoRelatedInstanceListElement();
342         SoRelatedInstanceListElement relatedInstanceListElement2 = new SoRelatedInstanceListElement();
343         relatedInstanceListElement1.setRelatedInstance(new SoRelatedInstance());
344         relatedInstanceListElement2.setRelatedInstance(new SoRelatedInstance());
345
346         // Service Item
347         relatedInstanceListElement1.getRelatedInstance().setInstanceId(vnfServiceItem.getServiceInstanceId());
348         relatedInstanceListElement1.getRelatedInstance().setModelInfo(new SoModelInfo());
349         relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelType("service");
350         relatedInstanceListElement1.getRelatedInstance().getModelInfo()
351                 .setModelInvariantId(vnfServiceItem.getModelInvariantId());
352         relatedInstanceListElement1.getRelatedInstance().getModelInfo()
353                 .setModelVersionId(vnfServiceItem.getModelVersionId());
354         relatedInstanceListElement1.getRelatedInstance().getModelInfo()
355                 .setModelName(aaiCqResponse.getModelVerByVersionId(vnfServiceItem.getModelVersionId()).getModelName());
356         relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelVersion(
357                 aaiCqResponse.getModelVerByVersionId(vnfServiceItem.getModelVersionId()).getModelVersion());
358
359
360         // VNF Item
361         relatedInstanceListElement2.getRelatedInstance().setInstanceId(vnfItem.getVnfId());
362         relatedInstanceListElement2.getRelatedInstance().setModelInfo(new SoModelInfo());
363         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelType("vnf");
364         relatedInstanceListElement2.getRelatedInstance().getModelInfo()
365                 .setModelInvariantId(vnfItem.getModelInvariantId());
366         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelVersionId(vnfItem.getModelVersionId());
367
368         relatedInstanceListElement2.getRelatedInstance().getModelInfo()
369                 .setModelName(aaiCqResponse.getModelVerByVersionId(vnfItem.getModelVersionId()).getModelName());
370         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelVersion(
371                 aaiCqResponse.getModelVerByVersionId(vnfItem.getModelVersionId()).getModelVersion());
372
373
374         relatedInstanceListElement2.getRelatedInstance().getModelInfo()
375                 .setModelCustomizationId(vnfItem.getModelCustomizationId());
376
377
378         // Insert the Service Item and VNF Item
379         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement1);
380         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement2);
381
382         // Request Parameters
383         buildRequestParameters(policy, request.getRequestDetails());
384
385         // Configuration Parameters
386         buildConfigurationParameters(policy, request.getRequestDetails());
387         // Save the instance IDs for the VNF and service to static fields
388         // vfModuleId is not required for the create vf-module
389         preserveInstanceIds(vnfItem.getVnfId(), vnfServiceItem.getServiceInstanceId(), null);
390         if (logger.isDebugEnabled()) {
391             logger.debug(CONSTRUCTED_SO_MSG, Serialization.gsonPretty.toJson(request));
392         }
393         return request;
394     }
395
396     /**
397      * constructs delete request for So.
398      *
399      * @param tenantItem Tenant from A&AI CQ request
400      * @param vnfItem Generic VNF from A&AI CQ request
401      * @param vnfServiceItem ServiceInstance from A&AI CQ request
402      * @param policy policy information
403      * @param cloudRegionItem CloudRegion from A&AI CQ request
404      * @return SoRequest deleted
405      */
406     private SoRequest constructDeleteRequestCq(Tenant tenantItem, GenericVnf vnfItem, ServiceInstance vnfServiceItem,
407             Policy policy, CloudRegion cloudRegionItem) {
408         SoRequest request = new SoRequest();
409         request.setOperationType(SoOperationType.DELETE_VF_MODULE);
410         request.setRequestDetails(new SoRequestDetails());
411         request.getRequestDetails().setRelatedInstanceList(null);
412         request.getRequestDetails().setConfigurationParameters(null);
413
414         // cloudConfiguration
415         request.getRequestDetails().setCloudConfiguration(constructCloudConfigurationCq(tenantItem, cloudRegionItem));
416         // modelInfo
417         request.getRequestDetails().setModelInfo(prepareSoModelInfo(policy));
418         // requestInfo
419         request.getRequestDetails().setRequestInfo(constructRequestInfo());
420         // Save the instance IDs for the VNF, service and vfModule to static fields
421         preserveInstanceIds(vnfItem.getVnfId(), vnfServiceItem.getServiceInstanceId(), null);
422
423         if (logger.isDebugEnabled()) {
424             logger.debug(CONSTRUCTED_SO_MSG, Serialization.gsonPretty.toJson(request));
425         }
426         return request;
427     }
428
429
430     /**
431      * Construct cloudConfiguration for the SO requestDetails. Overridden for custom query.
432      *
433      * @param tenantItem tenant item from A&AI named-query response
434      * @return SO cloud configuration
435      */
436     private SoCloudConfiguration constructCloudConfigurationCq(Tenant tenantItem, CloudRegion cloudRegionItem) {
437         SoCloudConfiguration cloudConfiguration = new SoCloudConfiguration();
438         cloudConfiguration.setTenantId(tenantItem.getTenantId());
439         cloudConfiguration.setLcpCloudRegionId(cloudRegionItem.getCloudRegionId());
440         return cloudConfiguration;
441     }
442
443 }