2 * ============LICENSE_START=======================================================
3 * SOActorServiceProvider
4 * ================================================================================
5 * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.controlloop.actor.so;
23 import java.util.Collections;
24 import java.util.List;
25 import org.drools.core.WorkingMemory;
26 import org.onap.policy.aai.AaiNqExtraProperty;
27 import org.onap.policy.aai.AaiNqInventoryResponseItem;
28 import org.onap.policy.aai.AaiNqResponseWrapper;
29 import org.onap.policy.controlloop.ControlLoopOperation;
30 import org.onap.policy.controlloop.VirtualControlLoopEvent;
31 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
32 import org.onap.policy.controlloop.policy.Policy;
33 import org.onap.policy.so.SOCloudConfiguration;
34 import org.onap.policy.so.SOManager;
35 import org.onap.policy.so.SOModelInfo;
36 import org.onap.policy.so.SORelatedInstance;
37 import org.onap.policy.so.SORelatedInstanceListElement;
38 import org.onap.policy.so.SORequest;
39 import org.onap.policy.so.SORequestDetails;
40 import org.onap.policy.so.SORequestInfo;
41 import org.onap.policy.so.SORequestParameters;
42 import org.onap.policy.so.util.Serialization;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import com.google.common.collect.ImmutableList;
46 import com.google.common.collect.ImmutableMap;
48 public class SOActorServiceProvider implements Actor {
49 private static final Logger logger = LoggerFactory.getLogger(SOActorServiceProvider.class);
51 // Strings for SO Actor
52 private static final String SO_ACTOR = "SO";
54 // Strings for targets
55 private static final String TARGET_VFC = "VFC";
57 // Strings for recipes
58 private static final String RECIPE_VF_MODULE_CREATE = "VF Module Create";
60 private static final ImmutableList<String> recipes = ImmutableList.of(RECIPE_VF_MODULE_CREATE);
61 private static final ImmutableMap<String, List<String>> targets = new ImmutableMap.Builder<String, List<String>>()
62 .put(RECIPE_VF_MODULE_CREATE, ImmutableList.of(TARGET_VFC)).build();
64 // Static variables required to hold the IDs of the last service item and VNF item. Note that in
65 // a multithreaded deployment this WILL break
66 private static String lastVNFItemVnfId;
67 private static String lastServiceItemServiceInstanceId;
70 public String actor() {
75 public List<String> recipes() {
76 return ImmutableList.copyOf(recipes);
80 public List<String> recipeTargets(String recipe) {
81 return ImmutableList.copyOf(targets.getOrDefault(recipe, Collections.emptyList()));
85 public List<String> recipePayloads(String recipe) {
86 return Collections.emptyList();
90 * Constructs a SO request conforming to the lcm API. The actual request is constructed and then
91 * placed in a wrapper object used to send through DMAAP.
93 * @param onset the event that is reporting the alert for policy to perform an action
94 * @param operation the control loop operation specifying the actor, operation, target, etc.
95 * @param policy the policy the was specified from the yaml generated by CLAMP or through the
97 * @param aaiResponseWrapper wrapper for AAI vserver named-query response
98 * @return a SO request conforming to the lcm API using the DMAAP wrapper
100 public SORequest constructRequest(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy, AaiNqResponseWrapper aaiResponseWrapper) {
101 String modelNamePropertyKey = "model-ver.model-name";
102 String modelVersionPropertyKey = "model-ver.model-version";
103 String modelVersionIdPropertyKey = "model-ver.model-version-id";
106 if (!SO_ACTOR.equals(policy.getActor()) || !RECIPE_VF_MODULE_CREATE.equals(policy.getRecipe())) {
107 // for future extension
111 // Perform named query request and handle response
112 if (aaiResponseWrapper == null) {
116 AaiNqInventoryResponseItem vnfItem;
117 AaiNqInventoryResponseItem vnfServiceItem;
118 AaiNqInventoryResponseItem tenantItem;
120 // Extract the items we're interested in from the response
122 vnfItem = aaiResponseWrapper.getAaiNqResponse().getInventoryResponseItems().get(0).getItems()
123 .getInventoryResponseItems().get(0);
124 } catch (Exception e) {
125 logger.error("VNF Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiResponseWrapper),
131 vnfServiceItem = vnfItem.getItems().getInventoryResponseItems().get(0);
132 } catch (Exception e) {
133 logger.error("VNF Service Item not found in AAI response {}",
134 Serialization.gsonPretty.toJson(aaiResponseWrapper), e);
139 tenantItem = aaiResponseWrapper.getAaiNqResponse().getInventoryResponseItems().get(0).getItems()
140 .getInventoryResponseItems().get(1);
141 } catch (Exception e) {
142 logger.error("Tenant Item not found in AAI response {}",
143 Serialization.gsonPretty.toJson(aaiResponseWrapper), e);
147 // Find the index for base vf module and non-base vf module
148 int baseIndex = findIndex(vnfItem.getItems().getInventoryResponseItems(), true);
149 int nonBaseIndex = findIndex(vnfItem.getItems().getInventoryResponseItems(), false);
151 // Report the error if either base vf module or non-base vf module is not found
152 if (baseIndex == -1 || nonBaseIndex == -1) {
153 logger.error("Either base or non-base vf module is not found from AAI response.");
158 // Construct SO Request
159 SORequest request = new SORequest();
161 // Do NOT send So the requestId, they do not support this field
163 request.setRequestDetails(new SORequestDetails());
164 request.getRequestDetails().setModelInfo(new SOModelInfo());
165 request.getRequestDetails().setCloudConfiguration(new SOCloudConfiguration());
166 request.getRequestDetails().setRequestInfo(new SORequestInfo());
167 request.getRequestDetails().setRequestParameters(new SORequestParameters());
168 request.getRequestDetails().getRequestParameters().setUserParams(null);
171 // cloudConfiguration
173 request.getRequestDetails().getCloudConfiguration().setTenantId(tenantItem.getTenant().getTenantId());
174 request.getRequestDetails().getCloudConfiguration().setLcpCloudRegionId(
175 tenantItem.getItems().getInventoryResponseItems().get(0).getCloudRegion().getCloudRegionId());
180 AaiNqInventoryResponseItem vfModuleItem = vnfItem.getItems().getInventoryResponseItems().get(nonBaseIndex);
182 request.getRequestDetails().getModelInfo().setModelType("vfModule");
183 request.getRequestDetails().getModelInfo()
184 .setModelInvariantId(vfModuleItem.getVfModule().getModelInvariantId());
185 request.getRequestDetails().getModelInfo().setModelVersionId(vfModuleItem.getVfModule().getModelVersionId());
187 for (AaiNqExtraProperty prop : vfModuleItem.getExtraProperties().getExtraProperty()) {
188 if (prop.getPropertyName().equals(modelNamePropertyKey)) {
189 request.getRequestDetails().getModelInfo().setModelName(prop.getPropertyValue());
190 } else if (prop.getPropertyName().equals(modelVersionPropertyKey)) {
191 request.getRequestDetails().getModelInfo().setModelVersion(prop.getPropertyValue());
198 request.getRequestDetails().getRequestInfo().setInstanceName(vnfItem.getItems().getInventoryResponseItems()
199 .get(baseIndex).getVfModule().getVfModuleName().replace("Vfmodule", "vDNS"));
200 request.getRequestDetails().getRequestInfo().setSource("POLICY");
201 request.getRequestDetails().getRequestInfo().setSuppressRollback(false);
202 request.getRequestDetails().getRequestInfo().setRequestorId("policy");
205 // relatedInstanceList
207 SORelatedInstanceListElement relatedInstanceListElement1 = new SORelatedInstanceListElement();
208 SORelatedInstanceListElement relatedInstanceListElement2 = new SORelatedInstanceListElement();
209 relatedInstanceListElement1.setRelatedInstance(new SORelatedInstance());
210 relatedInstanceListElement2.setRelatedInstance(new SORelatedInstance());
213 relatedInstanceListElement1.getRelatedInstance()
214 .setInstanceId(vnfServiceItem.getServiceInstance().getServiceInstanceId());
215 relatedInstanceListElement1.getRelatedInstance().setModelInfo(new SOModelInfo());
216 relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelType("service");
217 relatedInstanceListElement1.getRelatedInstance().getModelInfo()
218 .setModelInvariantId(vnfServiceItem.getServiceInstance().getModelInvariantId());
219 for (AaiNqExtraProperty prop : vnfServiceItem.getExtraProperties().getExtraProperty()) {
220 if (prop.getPropertyName().equals(modelNamePropertyKey)) {
221 relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelName(prop.getPropertyValue());
222 } else if (prop.getPropertyName().equals(modelVersionPropertyKey)) {
223 relatedInstanceListElement1.getRelatedInstance().getModelInfo()
224 .setModelVersion(prop.getPropertyValue());
225 } else if (prop.getPropertyName().equals(modelVersionIdPropertyKey)) {
226 relatedInstanceListElement1.getRelatedInstance().getModelInfo()
227 .setModelVersionId(prop.getPropertyValue());
232 relatedInstanceListElement2.getRelatedInstance().setInstanceId(vnfItem.getGenericVnf().getVnfId());
233 relatedInstanceListElement2.getRelatedInstance().setModelInfo(new SOModelInfo());
234 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelType("vnf");
235 relatedInstanceListElement2.getRelatedInstance().getModelInfo()
236 .setModelInvariantId(vnfItem.getGenericVnf().getModelInvariantId());
237 for (AaiNqExtraProperty prop : vnfItem.getExtraProperties().getExtraProperty()) {
238 if (prop.getPropertyName().equals(modelNamePropertyKey)) {
239 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelName(prop.getPropertyValue());
240 } else if (prop.getPropertyName().equals(modelVersionPropertyKey)) {
241 relatedInstanceListElement2.getRelatedInstance().getModelInfo()
242 .setModelVersion(prop.getPropertyValue());
243 } else if (prop.getPropertyName().equals(modelVersionIdPropertyKey)) {
244 relatedInstanceListElement2.getRelatedInstance().getModelInfo()
245 .setModelVersionId(prop.getPropertyValue());
248 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelCustomizationName(vnfItem
249 .getGenericVnf().getVnfType().substring(vnfItem.getGenericVnf().getVnfType().lastIndexOf('/') + 1));
251 // Insert the Service Item and VNF Item
252 request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement1);
253 request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement2);
255 // Save the instance IDs for the VNF and service to static fields
256 preserveInstanceIds(vnfItem.getGenericVnf().getVnfId(),
257 vnfServiceItem.getServiceInstance().getServiceInstanceId());
259 if (logger.isDebugEnabled()) {
260 logger.debug("SO request sent: {}", Serialization.gsonPretty.toJson(request));
267 * This method is needed to get the serviceInstanceId and vnfInstanceId which is used in the
270 * @param requestId the request Id
271 * @param wm the working memory
272 * @param request the request
274 public static void sendRequest(String requestId, WorkingMemory wm, Object request) {
275 SOManager soManager = new SOManager();
276 soManager.asyncSORestCall(requestId, wm, lastServiceItemServiceInstanceId, lastVNFItemVnfId,
277 (SORequest) request);
281 * Find the base index or non base index in a list of inventory response items.
283 * @param inventoryResponseItems the list of inventory response items
284 * @param baseIndexFlag true if we are searching for the base index, false if we are searching
285 * for the non base index
286 * @return the base or non base index or -1 if the index was not found
288 private int findIndex(List<AaiNqInventoryResponseItem> inventoryResponseItems, boolean baseIndexFlag) {
289 for (AaiNqInventoryResponseItem inventoryResponseItem : inventoryResponseItems) {
290 if (inventoryResponseItem.getVfModule() != null
291 && baseIndexFlag == inventoryResponseItem.getVfModule().getIsBaseVfModule()) {
292 return inventoryResponseItems.indexOf(inventoryResponseItem);
300 * Find the number of non base modules present in API response object.
302 * @param inventoryResponseItems the list of inventory response items
303 * @return number of non base index modules
306 @SuppressWarnings("unused")
307 private int findNonBaseModules(List<AaiNqInventoryResponseItem> inventoryResponseItems) {
308 int nonBaseModuleCount = 0;
309 for (AaiNqInventoryResponseItem inventoryResponseItem : inventoryResponseItems) {
310 if (inventoryResponseItem.getVfModule() != null
311 && (!inventoryResponseItem.getVfModule().getIsBaseVfModule())) {
312 nonBaseModuleCount++;
315 return nonBaseModuleCount;
319 * This method is called to remember the last service instance ID and VNF Item VNF ID. Note
320 * these fields are static, beware for multithreaded deployments
322 * @param vnfInstanceId update the last VNF instance ID to this value
323 * @param serviceInstanceId update the last service instance ID to this value
325 private static void preserveInstanceIds(final String vnfInstanceId, final String serviceInstanceId) {
326 lastVNFItemVnfId = vnfInstanceId;
327 lastServiceItemServiceInstanceId = serviceInstanceId;