0316961234bebd90cf87fa154db9a0a183dc85da
[vfc/nfvo/driver/vnfm/svnfm.git] / nokiav2 / driver / src / main / java / org / onap / vfc / nfvo / driver / vnfm / svnfm / nokia / onap / vfc / VfcGrantManager.java
1 /*
2  * Copyright 2016-2017, Nokia Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.vfc;
18
19 import com.google.common.annotations.VisibleForTesting;
20 import com.google.gson.Gson;
21 import com.google.gson.JsonArray;
22 import com.google.gson.JsonElement;
23 import com.google.gson.JsonObject;
24 import com.nokia.cbam.lcm.v32.model.VnfInfo;
25 import com.nokia.cbam.lcm.v32.model.VnfcResourceInfo;
26 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.IGrantManager;
27 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions;
28 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CatalogManager;
29 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider;
30 import org.onap.vnfmdriver.model.*;
31 import org.slf4j.Logger;
32 import org.springframework.beans.factory.annotation.Autowired;
33 import org.springframework.context.annotation.Conditional;
34 import org.springframework.stereotype.Component;
35 import org.yaml.snakeyaml.Yaml;
36
37 import java.util.*;
38
39 import static com.nokia.cbam.lcm.v32.model.InstantiationState.INSTANTIATED;
40 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
41 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.child;
42 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCM_API_VERSION;
43 import static org.onap.vnfmdriver.model.OperationType.TERMINAL;
44 import static org.slf4j.LoggerFactory.getLogger;
45
46 /**
47  * Responsible for handling granting before the execution of a VNF operation
48  */
49 @Component
50 @Conditional(value = Conditions.UseForVfc.class)
51 public class VfcGrantManager implements IGrantManager {
52     private static Logger logger = getLogger(VfcGrantManager.class);
53     private final CatalogManager catalogManager;
54     private final CbamRestApiProvider cbamRestApiProvider;
55     private final VfcRestApiProvider vfcRestApiProvider;
56
57     @Autowired
58     VfcGrantManager(CatalogManager catalogManager, CbamRestApiProvider cbamRestApiProvider, VfcRestApiProvider vfcRestApiProvider) {
59         this.catalogManager = catalogManager;
60         this.cbamRestApiProvider = cbamRestApiProvider;
61         this.vfcRestApiProvider = vfcRestApiProvider;
62     }
63
64     @Override
65     public void requestGrantForHeal(String vnfmId, String vnfId, String vimId, String onapCsarId, VnfHealRequest request, String jobId) {
66         GrantVNFRequest grantRequest = buildGrantRequest(vnfmId, vimId, onapCsarId, jobId, OperationType.HEAL);
67         ResourceChange resourceChange = new ResourceChange();
68         resourceChange.setType(ChangeType.VDU);
69         resourceChange.setVdu(request.getAffectedvm().getVduid());
70         resourceChange.setResourceDefinitionId(UUID.randomUUID().toString());
71         grantRequest.getRemoveResource().add(resourceChange);
72         grantRequest.getAddResource().add(resourceChange);
73         grantRequest.setVnfInstanceId(vnfId);
74         requestGrant(grantRequest);
75     }
76
77     @Override
78     public void requestGrantForScale(String vnfmId, String vnfId, String vimId, String onapCsarId, VnfScaleRequest request, String jobId) {
79         String cbamVnfdId;
80         try {
81             com.nokia.cbam.lcm.v32.model.VnfInfo vnf = cbamRestApiProvider.getCbamLcmApi(vnfmId).vnfsVnfInstanceIdGet(vnfId, NOKIA_LCM_API_VERSION).blockingFirst();
82             cbamVnfdId = vnf.getVnfdId();
83         } catch (Exception e) {
84             throw buildFatalFailure(logger, "Unable to query VNF " + vnfId, e);
85         }
86         OperationType operationType = ScaleDirection.IN.equals(request.getType()) ? OperationType.SCALEIN : OperationType.SCALEOUT;
87         GrantVNFRequest grantRequest = buildGrantRequest(vnfmId, vimId, onapCsarId, jobId, operationType);
88         String vnfdContent = catalogManager.getCbamVnfdContent(vnfmId, cbamVnfdId);
89         Set<ResourceChange> resourceChanges = calculateResourceChangeDuringScaling(vnfdContent, request.getAspectId(), Integer.parseInt(request.getNumberOfSteps()));
90         if (request.getType() == ScaleDirection.IN) {
91             grantRequest.getRemoveResource().addAll(resourceChanges);
92
93         } else {
94             grantRequest.getAddResource().addAll(resourceChanges);
95         }
96         grantRequest.setVnfInstanceId(vnfId);
97         requestGrant(grantRequest);
98     }
99
100     @Override
101     public void requestGrantForTerminate(String vnfmId, String vnfId, String vimId, String onapVnfdId, VnfInfo vnf, String jobId) {
102         if (vnf.getInstantiationState() == INSTANTIATED) {
103             GrantVNFRequest grantRequest;
104             try {
105                 grantRequest = buildGrantRequest(vnfmId, vimId, onapVnfdId, jobId, TERMINAL);
106                 grantRequest.setVnfInstanceId(vnfId);
107                 addVnfcsToGrant(vnf, grantRequest);
108             } catch (Exception e) {
109                 throw buildFatalFailure(logger, "Unable to prepare grant request for termination", e);
110             }
111             requestGrant(grantRequest);
112         }
113     }
114
115     private void addVnfcsToGrant(VnfInfo vnf, GrantVNFRequest grantRequest) {
116         //VNF is instantiated but has no VNFC
117         if (vnf.getInstantiatedVnfInfo().getVnfcResourceInfo() != null) {
118             for (VnfcResourceInfo vnfc : vnf.getInstantiatedVnfInfo().getVnfcResourceInfo()) {
119                 ResourceChange resourceChange = new ResourceChange();
120                 grantRequest.getRemoveResource().add(resourceChange);
121                 resourceChange.setVdu(vnfc.getVduId());
122                 resourceChange.setType(ChangeType.VDU);
123                 resourceChange.setResourceDefinitionId(UUID.randomUUID().toString());
124             }
125         }
126     }
127
128     @Override
129     public GrantVNFResponseVim requestGrantForInstantiate(String vnfmId, String vnfId, String vimId, String onapVnfdId, String instantiationLevelId, String cbamVnfdContent, String jobId) {
130         GrantVNFRequest grantRequest;
131         try {
132             grantRequest = buildGrantRequest(vnfmId, vimId, onapVnfdId, jobId, OperationType.INSTANTIATE);
133             grantRequest.setVnfInstanceId(vnfId);
134             grantRequest.setAddResource(new ArrayList<>());
135             grantRequest.getAddResource().addAll(calculateResourceChangeDuringInstantiate(cbamVnfdContent, instantiationLevelId));
136         } catch (Exception e) {
137             throw buildFatalFailure(logger, "Unable to prepare grant request for instantiation", e);
138         }
139         return requestGrant(grantRequest);
140     }
141
142     private GrantVNFRequest buildGrantRequest(String vnfmId, String vimId, String onapCsarId, String jobId, OperationType operationType) {
143         GrantVNFRequest grantVNFRequest = new GrantVNFRequest();
144         //FIXME
145         //Currently the grant request sent to VF-C must contain the VIM identifier in the
146         //grant response (normally in ETSI VIM identifier is received in the grant response
147         //from ETSI orchestrator the vimId parameter should be removed from this POJO
148         //to be able to fix this https://jira.onap.org/browse/VFC-603 must be solved
149         //the vimId should be removed from the AdditionalGrantParams structure
150         grantVNFRequest.setAdditionalParam(new AdditionalGrantParams(vnfmId, vimId));
151         grantVNFRequest.setVnfDescriptorId(onapCsarId);
152         grantVNFRequest.setJobId(jobId);
153         grantVNFRequest.setLifecycleOperation(operationType);
154         grantVNFRequest.setAddResource(new ArrayList<>());
155         grantVNFRequest.setRemoveResource(new ArrayList<>());
156         return grantVNFRequest;
157     }
158
159     private GrantVNFResponseVim requestGrant(GrantVNFRequest grantRequest) {
160         try {
161             return vfcRestApiProvider.getNsLcmApi().grantvnf(grantRequest).execute().body().getVim();
162         } catch (Exception e) {
163             throw buildFatalFailure(logger, "Unable to request grant", e);
164         }
165     }
166
167     private Set<ResourceChange> calculateResourceChangeDuringInstantiate(String vnfdContent, String instantiationLevelId) {
168         JsonObject root = new Gson().toJsonTree(new Yaml().load(vnfdContent)).getAsJsonObject();
169         JsonObject capabilities = child(child(child(root, "topology_template"), "substitution_mappings"), "capabilities");
170         JsonObject deploymentFlavorProperties = child(child(capabilities, "deployment_flavour"), "properties");
171         JsonObject instantiationLevels = child(deploymentFlavorProperties, "instantiation_levels");
172         Set<ResourceChange> resourceChanges = new HashSet<>();
173         for (Map.Entry<String, JsonElement> vdu_level : child(child(instantiationLevels, instantiationLevelId), ("vdu_levels")).entrySet()) {
174             JsonElement numberOfInstances = vdu_level.getValue().getAsJsonObject().get("number_of_instances");
175             for (int i = 0; i < numberOfInstances.getAsLong(); i++) {
176                 ResourceChange resourceChange = new ResourceChange();
177                 resourceChanges.add(resourceChange);
178                 resourceChange.setVdu(vdu_level.getKey());
179                 resourceChange.setType(ChangeType.VDU);
180                 resourceChange.setResourceDefinitionId(UUID.randomUUID().toString());
181             }
182         }
183         return resourceChanges;
184     }
185
186     private Set<ResourceChange> calculateResourceChangeDuringScaling(String vnfdContent, String aspectId, int steps) {
187         JsonObject root = new Gson().toJsonTree(new Yaml().load(vnfdContent)).getAsJsonObject();
188         Set<ResourceChange> resourceChanges = new HashSet<>();
189         JsonArray policies = child(root, "topology_template").getAsJsonObject().get("policies").getAsJsonArray();
190         for (JsonElement policy : policies) {
191             if ("heat_mapping".equals(policy.getAsJsonObject().entrySet().iterator().next().getKey())) {
192                 JsonObject aspects = policy.getAsJsonObject().entrySet().iterator().next().getValue().getAsJsonObject().get("properties").getAsJsonObject().get("aspects").getAsJsonObject();
193                 JsonObject aspect = child(aspects, aspectId);
194                 if (aspect.has("vdus")) {
195                     addChangesForAspect(steps, resourceChanges, aspect);
196                 }
197             }
198         }
199         return resourceChanges;
200     }
201
202     private void addChangesForAspect(int steps, Set<ResourceChange> resourceChanges, JsonObject aspect) {
203         for (Map.Entry<String, JsonElement> vdu : aspect.get("vdus").getAsJsonObject().entrySet()) {
204             String vduId = vdu.getKey();
205             for (int step = 0; step < steps; step++) {
206                 for (int i = 0; i < vdu.getValue().getAsJsonArray().size(); i++) {
207                     ResourceChange resourceChange = new ResourceChange();
208                     resourceChange.setVdu(vduId);
209                     resourceChange.setType(ChangeType.VDU);
210                     resourceChange.setResourceDefinitionId(UUID.randomUUID().toString());
211                     resourceChanges.add(resourceChange);
212                 }
213             }
214         }
215     }
216
217     /**
218      * Represents the mandatory parameters that must be sent during grant request to VF-C
219      */
220     @VisibleForTesting
221     static class AdditionalGrantParams {
222         private final String vnfmId;
223         private final String vimId;
224
225         AdditionalGrantParams(String vnfmId, String vimId) {
226             this.vnfmId = vnfmId;
227             this.vimId = vimId;
228         }
229
230         /**
231          * @return the identifier of the VNFM requesting the grant
232          */
233         public String getVnfmId() {
234             return vnfmId;
235         }
236
237         /**
238          * @return the identifier of the VIM for which the grant is requested
239          */
240         public String getVimId() {
241             return vimId;
242         }
243     }
244 }