c934c6110f25f96b600187ddf1a751ba529516c0
[policy/drools-applications.git] /
1 /*
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.onap.policy.controlloop.actor.so;
22
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;
47
48 public class SOActorServiceProvider implements Actor {
49     private static final Logger logger = LoggerFactory.getLogger(SOActorServiceProvider.class);
50
51     // Strings for SO Actor
52     private static final String SO_ACTOR = "SO";
53
54     // Strings for targets
55     private static final String TARGET_VFC = "VFC";
56
57     // Strings for recipes
58     private static final String RECIPE_VF_MODULE_CREATE = "VF Module Create";
59
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();
63
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;
68
69     @Override
70     public String actor() {
71         return SO_ACTOR;
72     }
73
74     @Override
75     public List<String> recipes() {
76         return ImmutableList.copyOf(recipes);
77     }
78
79     @Override
80     public List<String> recipeTargets(String recipe) {
81         return ImmutableList.copyOf(targets.getOrDefault(recipe, Collections.emptyList()));
82     }
83
84     @Override
85     public List<String> recipePayloads(String recipe) {
86         return Collections.emptyList();
87     }
88
89     /**
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.
92      *
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
96      *        Policy GUI/API
97      * @param aaiResponseWrapper wrapper for AAI vserver named-query response
98      * @return a SO request conforming to the lcm API using the DMAAP wrapper
99      */
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";
104
105
106         if (!SO_ACTOR.equals(policy.getActor()) || !RECIPE_VF_MODULE_CREATE.equals(policy.getRecipe())) {
107             // for future extension
108             return null;
109         }
110
111         // Perform named query request and handle response
112         if (aaiResponseWrapper == null) {
113             return null;
114         }
115
116         AaiNqInventoryResponseItem vnfItem;
117         AaiNqInventoryResponseItem vnfServiceItem;
118         AaiNqInventoryResponseItem tenantItem;
119
120         // Extract the items we're interested in from the response
121         try {
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),
126                     e);
127             return null;
128         }
129
130         try {
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);
135             return null;
136         }
137
138         try {
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);
144             return null;
145         }
146
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);
150
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.");
154             return null;
155         }
156
157
158         // Construct SO Request
159         SORequest request = new SORequest();
160         //
161         // Do NOT send So the requestId, they do not support this field
162         //
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);
169
170         //
171         // cloudConfiguration
172         //
173         request.getRequestDetails().getCloudConfiguration().setTenantId(tenantItem.getTenant().getTenantId());
174         request.getRequestDetails().getCloudConfiguration().setLcpCloudRegionId(
175                 tenantItem.getItems().getInventoryResponseItems().get(0).getCloudRegion().getCloudRegionId());
176
177         //
178         // modelInfo
179         //
180         AaiNqInventoryResponseItem vfModuleItem = vnfItem.getItems().getInventoryResponseItems().get(nonBaseIndex);
181
182         request.getRequestDetails().getModelInfo().setModelType("vfModule");
183         request.getRequestDetails().getModelInfo()
184                 .setModelInvariantId(vfModuleItem.getVfModule().getModelInvariantId());
185         request.getRequestDetails().getModelInfo().setModelVersionId(vfModuleItem.getVfModule().getModelVersionId());
186
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());
192             }
193         }
194
195         //
196         // requestInfo
197         //
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");
203
204         //
205         // relatedInstanceList
206         //
207         SORelatedInstanceListElement relatedInstanceListElement1 = new SORelatedInstanceListElement();
208         SORelatedInstanceListElement relatedInstanceListElement2 = new SORelatedInstanceListElement();
209         relatedInstanceListElement1.setRelatedInstance(new SORelatedInstance());
210         relatedInstanceListElement2.setRelatedInstance(new SORelatedInstance());
211
212         // Service Item
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());
228             }
229         }
230
231         // VNF Item
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());
246             }
247         }
248         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelCustomizationName(vnfItem
249                 .getGenericVnf().getVnfType().substring(vnfItem.getGenericVnf().getVnfType().lastIndexOf('/') + 1));
250
251         // Insert the Service Item and VNF Item
252         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement1);
253         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement2);
254
255         // Save the instance IDs for the VNF and service to static fields
256         preserveInstanceIds(vnfItem.getGenericVnf().getVnfId(),
257                 vnfServiceItem.getServiceInstance().getServiceInstanceId());
258
259         if (logger.isDebugEnabled()) {
260             logger.debug("SO request sent: {}", Serialization.gsonPretty.toJson(request));
261         }
262
263         return request;
264     }
265
266     /**
267      * This method is needed to get the serviceInstanceId and vnfInstanceId which is used in the
268      * asyncSORestCall.
269      *
270      * @param requestId the request Id
271      * @param wm the working memory
272      * @param request the request
273      */
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);
278     }
279
280     /**
281      * Find the base index or non base index in a list of inventory response items.
282      *
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
287      */
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);
293             }
294         }
295
296         return -1;
297     }
298
299     /**
300      * Find the number of non base modules present in API response object.
301      *
302      * @param inventoryResponseItems the list of inventory response items
303      * @return number of non base index modules
304      */
305
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++;
313             }
314         }
315         return nonBaseModuleCount;
316     }
317
318     /**
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
321      *
322      * @param vnfInstanceId update the last VNF instance ID to this value
323      * @param serviceInstanceId update the last service instance ID to this value
324      */
325     private static void preserveInstanceIds(final String vnfInstanceId, final String serviceInstanceId) {
326         lastVNFItemVnfId = vnfInstanceId;
327         lastServiceItemServiceInstanceId = serviceInstanceId;
328     }
329 }