2 * ============LICENSE_START=======================================================
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 package org.onap.policy.controlloop.actor.so;
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;
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;
56 public class SoActor extends HttpActor<HttpPollingActorParams> {
57 private static final Logger logger = LoggerFactory.getLogger(SoActor.class);
59 public static final String NAME = "SO";
61 // TODO old code: remove lines down to **HERE**
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: {}";
66 // Strings for targets
67 private static final String TARGET_VFC = "VFC";
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";
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();
79 // name of request parameters within policy payload
80 public static final String REQ_PARAM_NM = "requestParameters";
82 // name of configuration parameters within policy payload
83 public static final String CONFIG_PARAM_NM = "configurationParameters";
85 // used to decode configuration parameters via gson
86 private static final Type CONFIG_TYPE = new TypeToken<List<Map<String, String>>>() {}.getType();
88 // Static variables required to hold the IDs of the last service item, VNF item and VF Module.
90 // a multithreaded deployment this WILL break
91 private static String lastVNFItemVnfId;
92 private static String lastServiceItemServiceInstanceId;
93 private static String lastVfModuleItemVfModuleInstanceId;
98 * Constructs the object.
101 super(NAME, HttpPollingActorParams.class);
103 addOperator(new HttpPollingOperator(NAME, VfModuleCreate.NAME, VfModuleCreate::new));
104 addOperator(new HttpPollingOperator(NAME, VfModuleDelete.NAME, VfModuleDelete::new));
107 // TODO old code: remove lines down to **HERE**
110 public String actor() {
115 public List<String> recipes() {
116 return ImmutableList.copyOf(recipes);
120 public List<String> recipeTargets(String recipe) {
121 return ImmutableList.copyOf(targets.getOrDefault(recipe, Collections.emptyList()));
125 public List<String> recipePayloads(String recipe) {
126 return Collections.emptyList();
129 private SoModelInfo prepareSoModelInfo(Policy policy) {
131 if (policy.getTarget() == null || policy.getTarget().getModelCustomizationId() == null
132 || policy.getTarget().getModelInvariantId() == null) {
136 if (policy.getTarget().getModelName() == null || policy.getTarget().getModelVersion() == null
137 || policy.getTarget().getModelVersionId() == null) {
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");
152 * Construct requestInfo for the SO requestDetails.
154 * @return SO request information
156 private SoRequestInfo constructRequestInfo() {
157 SoRequestInfo soRequestInfo = new SoRequestInfo();
158 soRequestInfo.setSource("POLICY");
159 soRequestInfo.setSuppressRollback(false);
160 soRequestInfo.setRequestorId("policy");
161 return soRequestInfo;
165 * This method is needed to get the serviceInstanceId and vnfInstanceId which is used in the asyncSORestCall.
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
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);
183 * Builds the request parameters from the policy payload.
185 * @param policy the policy
186 * @param request request into which to stick the request parameters
188 private void buildRequestParameters(Policy policy, SoRequestDetails request) {
189 // assume null until proven otherwise
190 request.setRequestParameters(null);
192 if (policy.getPayload() == null) {
196 String json = policy.getPayload().get(REQ_PARAM_NM);
201 request.setRequestParameters(Serialization.gsonPretty.fromJson(json, SoRequestParameters.class));
205 * Builds the configuration parameters from the policy payload.
207 * @param policy the policy
208 * @param request request into which to stick the configuration parameters
210 private void buildConfigurationParameters(Policy policy, SoRequestDetails request) {
211 // assume null until proven otherwise
212 request.setConfigurationParameters(null);
214 if (policy.getPayload() == null) {
218 String json = policy.getPayload().get(CONFIG_PARAM_NM);
223 request.setConfigurationParameters(Serialization.gsonPretty.fromJson(json, CONFIG_TYPE));
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
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
234 private static void preserveInstanceIds(final String vnfInstanceId, final String serviceInstanceId,
235 final String vfModuleId) {
236 lastVNFItemVnfId = vnfInstanceId;
237 lastServiceItemServiceInstanceId = serviceInstanceId;
238 lastVfModuleItemVfModuleInstanceId = vfModuleId;
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.
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
251 public SoRequest constructRequestCq(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy,
252 AaiCqResponse aaiCqResponse) {
253 if (!NAME.equals(policy.getActor()) || !recipes().contains(policy.getRecipe())) {
257 // A&AI named query should have been performed by now. If not, return null
258 if (aaiCqResponse == null) {
262 SoModelInfo soModelInfo = prepareSoModelInfo(policy);
264 // Report the error vf module is not found
265 if (soModelInfo == null) {
266 logger.error("vf module is not found.");
271 ServiceInstance vnfServiceItem;
273 CloudRegion cloudRegionItem;
275 // Extract the items we're interested in from the response
277 vnfItem = aaiCqResponse.getGenericVnfByVfModuleModelInvariantId(soModelInfo.getModelInvariantId());
278 //Report VNF not found
279 if (vnfItem == null) {
280 logger.error("Generic Vnf is not found.");
283 } catch (Exception e) {
284 logger.error("VNF Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiCqResponse), e);
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);
297 tenantItem = aaiCqResponse.getDefaultTenant();
298 } catch (Exception e) {
299 logger.error(TENANT_NOT_FOUND, Serialization.gsonPretty.toJson(aaiCqResponse), e);
304 cloudRegionItem = aaiCqResponse.getDefaultCloudRegion();
305 } catch (Exception e) {
306 logger.error(TENANT_NOT_FOUND, Serialization.gsonPretty.toJson(aaiCqResponse), e);
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,
316 } else if (RECIPE_VF_MODULE_DELETE.equals(policy.getRecipe())) {
317 return constructDeleteRequestCq(tenantItem, vnfItem, vnfServiceItem, policy, cloudRegionItem);
324 * Construct the So request, based on Custom Query response from A&AI.
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
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);
341 // Do NOT send So the requestId, they do not support this field
343 request.setRequestDetails(new SoRequestDetails());
344 request.getRequestDetails().setRequestParameters(new SoRequestParameters());
345 request.getRequestDetails().getRequestParameters().setUserParams(null);
347 // cloudConfiguration
348 request.getRequestDetails().setCloudConfiguration(constructCloudConfigurationCq(tenantItem, cloudRegionItem));
350 request.getRequestDetails().setModelInfo(vfModuleItem);
354 request.getRequestDetails().setRequestInfo(constructRequestInfo());
355 request.getRequestDetails().getRequestInfo().setInstanceName("vfModuleName");
357 // relatedInstanceList
358 SoRelatedInstanceListElement relatedInstanceListElement1 = new SoRelatedInstanceListElement();
359 SoRelatedInstanceListElement relatedInstanceListElement2 = new SoRelatedInstanceListElement();
360 relatedInstanceListElement1.setRelatedInstance(new SoRelatedInstance());
361 relatedInstanceListElement2.setRelatedInstance(new SoRelatedInstance());
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());
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());
385 relatedInstanceListElement2.getRelatedInstance().getModelInfo()
386 .setModelName(aaiCqResponse.getModelVerByVersionId(vnfItem.getModelVersionId()).getModelName());
387 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelVersion(
388 aaiCqResponse.getModelVerByVersionId(vnfItem.getModelVersionId()).getModelVersion());
391 relatedInstanceListElement2.getRelatedInstance().getModelInfo()
392 .setModelCustomizationId(vnfItem.getModelCustomizationId());
395 // Insert the Service Item and VNF Item
396 request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement1);
397 request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement2);
399 // Request Parameters
400 buildRequestParameters(policy, request.getRequestDetails());
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));
414 * constructs delete request for So.
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
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);
431 // cloudConfiguration
432 request.getRequestDetails().setCloudConfiguration(constructCloudConfigurationCq(tenantItem, cloudRegionItem));
434 request.getRequestDetails().setModelInfo(prepareSoModelInfo(policy));
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);
440 if (logger.isDebugEnabled()) {
441 logger.debug(CONSTRUCTED_SO_MSG, Serialization.gsonPretty.toJson(request));
448 * Construct cloudConfiguration for the SO requestDetails. Overridden for custom query.
450 * @param tenantItem tenant item from A&AI named-query response
451 * @return SO cloud configuration
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;