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