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