f68c6f6761f6079299d1ebf286e6111e65505aed
[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         AaiNqInventoryResponseItem baseItem = findVfModule(aaiResponseWrapper, true);
149         AaiNqInventoryResponseItem vfModuleItem = findVfModule(aaiResponseWrapper, false);
150
151         // Report the error if either base vf module or non-base vf module is not found
152         if (baseItem == null || vfModuleItem == null) {
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         request.getRequestDetails().getModelInfo().setModelType("vfModule");
181         request.getRequestDetails().getModelInfo()
182                 .setModelInvariantId(vfModuleItem.getVfModule().getModelInvariantId());
183         request.getRequestDetails().getModelInfo().setModelVersionId(vfModuleItem.getVfModule().getModelVersionId());
184
185         for (AaiNqExtraProperty prop : vfModuleItem.getExtraProperties().getExtraProperty()) {
186             if (prop.getPropertyName().equals(modelNamePropertyKey)) {
187                 request.getRequestDetails().getModelInfo().setModelName(prop.getPropertyValue());
188             } else if (prop.getPropertyName().equals(modelVersionPropertyKey)) {
189                 request.getRequestDetails().getModelInfo().setModelVersion(prop.getPropertyValue());
190             }
191         }
192
193         //
194         // requestInfo
195         //
196         request.getRequestDetails().getRequestInfo().setInstanceName(aaiResponseWrapper.genVfModuleName());
197         request.getRequestDetails().getRequestInfo().setSource("POLICY");
198         request.getRequestDetails().getRequestInfo().setSuppressRollback(false);
199         request.getRequestDetails().getRequestInfo().setRequestorId("policy");
200
201         //
202         // relatedInstanceList
203         //
204         SORelatedInstanceListElement relatedInstanceListElement1 = new SORelatedInstanceListElement();
205         SORelatedInstanceListElement relatedInstanceListElement2 = new SORelatedInstanceListElement();
206         relatedInstanceListElement1.setRelatedInstance(new SORelatedInstance());
207         relatedInstanceListElement2.setRelatedInstance(new SORelatedInstance());
208
209         // Service Item
210         relatedInstanceListElement1.getRelatedInstance()
211                 .setInstanceId(vnfServiceItem.getServiceInstance().getServiceInstanceId());
212         relatedInstanceListElement1.getRelatedInstance().setModelInfo(new SOModelInfo());
213         relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelType("service");
214         relatedInstanceListElement1.getRelatedInstance().getModelInfo()
215                 .setModelInvariantId(vnfServiceItem.getServiceInstance().getModelInvariantId());
216         for (AaiNqExtraProperty prop : vnfServiceItem.getExtraProperties().getExtraProperty()) {
217             if (prop.getPropertyName().equals(modelNamePropertyKey)) {
218                 relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelName(prop.getPropertyValue());
219             } else if (prop.getPropertyName().equals(modelVersionPropertyKey)) {
220                 relatedInstanceListElement1.getRelatedInstance().getModelInfo()
221                         .setModelVersion(prop.getPropertyValue());
222             } else if (prop.getPropertyName().equals(modelVersionIdPropertyKey)) {
223               relatedInstanceListElement1.getRelatedInstance().getModelInfo()
224                       .setModelVersionId(prop.getPropertyValue());
225             }
226         }
227
228         // VNF Item
229         relatedInstanceListElement2.getRelatedInstance().setInstanceId(vnfItem.getGenericVnf().getVnfId());
230         relatedInstanceListElement2.getRelatedInstance().setModelInfo(new SOModelInfo());
231         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelType("vnf");
232         relatedInstanceListElement2.getRelatedInstance().getModelInfo()
233                 .setModelInvariantId(vnfItem.getGenericVnf().getModelInvariantId());
234         for (AaiNqExtraProperty prop : vnfItem.getExtraProperties().getExtraProperty()) {
235             if (prop.getPropertyName().equals(modelNamePropertyKey)) {
236                 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelName(prop.getPropertyValue());
237             } else if (prop.getPropertyName().equals(modelVersionPropertyKey)) {
238                 relatedInstanceListElement2.getRelatedInstance().getModelInfo()
239                         .setModelVersion(prop.getPropertyValue());
240             } else if (prop.getPropertyName().equals(modelVersionIdPropertyKey)) {
241                 relatedInstanceListElement2.getRelatedInstance().getModelInfo()
242                         .setModelVersionId(prop.getPropertyValue());
243             }
244         }
245         relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelCustomizationName(vnfItem
246                 .getGenericVnf().getVnfType().substring(vnfItem.getGenericVnf().getVnfType().lastIndexOf('/') + 1));
247
248         // Insert the Service Item and VNF Item
249         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement1);
250         request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement2);
251
252         // Save the instance IDs for the VNF and service to static fields
253         preserveInstanceIds(vnfItem.getGenericVnf().getVnfId(),
254                 vnfServiceItem.getServiceInstance().getServiceInstanceId());
255
256         if (logger.isDebugEnabled()) {
257             logger.debug("SO request sent: {}", Serialization.gsonPretty.toJson(request));
258         }
259
260         return request;
261     }
262
263     /**
264      * This method is needed to get the serviceInstanceId and vnfInstanceId which is used in the
265      * asyncSORestCall.
266      *
267      * @param requestId the request Id
268      * @param wm the working memory
269      * @param request the request
270      */
271     public static void sendRequest(String requestId, WorkingMemory wm, Object request) {
272         SOManager soManager = new SOManager();
273         soManager.asyncSORestCall(requestId, wm, lastServiceItemServiceInstanceId, lastVNFItemVnfId,
274                 (SORequest) request);
275     }
276
277     /**
278      * Find the base or non base VF module item in an AAI response.
279      *
280      * @param aaiResponseWrapper the AAI response containing the VF modules
281      * @param baseFlag true if we are searching for the base, false if we are searching
282      *        for the non base
283      * @return the base or non base VF module item or null if the module was not found
284      */
285     private AaiNqInventoryResponseItem findVfModule(AaiNqResponseWrapper aaiResponseWrapper, boolean baseFlag) {
286         List<AaiNqInventoryResponseItem> lst = aaiResponseWrapper.getVfModuleItems(baseFlag);
287         return (lst == null || lst.isEmpty() ? null : lst.get(0));
288     }
289
290     /**
291      * This method is called to remember the last service instance ID and VNF Item VNF ID. Note
292      * these fields are static, beware for multithreaded deployments
293      *
294      * @param vnfInstanceId update the last VNF instance ID to this value
295      * @param serviceInstanceId update the last service instance ID to this value
296      */
297     private static void preserveInstanceIds(final String vnfInstanceId, final String serviceInstanceId) {
298         lastVNFItemVnfId = vnfInstanceId;
299         lastServiceItemServiceInstanceId = serviceInstanceId;
300     }
301 }