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