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