2  * Copyright 2016-2017, Nokia Corporation
 
   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
 
   8  *     http://www.apache.org/licenses/LICENSE-2.0
 
  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.
 
  17 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.vfc;
 
  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;
 
  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.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;
 
  38 import static com.nokia.cbam.lcm.v32.model.InstantiationState.INSTANTIATED;
 
  39 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
 
  40 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.child;
 
  41 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCM_API_VERSION;
 
  42 import static org.onap.vnfmdriver.model.OperationType.TERMINAL;
 
  43 import static org.slf4j.LoggerFactory.getLogger;
 
  46  * Responsible for handling granting before the execution of a VNF operation
 
  49 @Conditional(value = Conditions.UseForVfc.class)
 
  50 public class VfcGrantManager implements IGrantManager {
 
  51     private static Logger logger = getLogger(VfcGrantManager.class);
 
  52     private final CatalogManager catalogManager;
 
  53     private final CbamRestApiProvider cbamRestApiProvider;
 
  54     private final VfcRestApiProvider vfcRestApiProvider;
 
  57     VfcGrantManager(CatalogManager catalogManager, CbamRestApiProvider cbamRestApiProvider, VfcRestApiProvider vfcRestApiProvider) {
 
  58         this.catalogManager = catalogManager;
 
  59         this.cbamRestApiProvider = cbamRestApiProvider;
 
  60         this.vfcRestApiProvider = vfcRestApiProvider;
 
  64     public void requestGrantForHeal(String vnfmId, String vnfId, String vimId, String onapCsarId, VnfHealRequest request, String jobId) {
 
  65         GrantVNFRequest grantRequest = buildGrantRequest(vnfmId, vimId, onapCsarId, jobId, OperationType.HEAL);
 
  66         ResourceChange resourceChange = new ResourceChange();
 
  67         resourceChange.setType(ChangeType.VDU);
 
  68         resourceChange.setVdu(request.getAffectedvm().getVduid());
 
  69         resourceChange.setResourceDefinitionId(UUID.randomUUID().toString());
 
  70         grantRequest.getRemoveResource().add(resourceChange);
 
  71         grantRequest.getAddResource().add(resourceChange);
 
  72         grantRequest.setVnfInstanceId(vnfId);
 
  73         requestGrant(grantRequest);
 
  77     public void requestGrantForScale(String vnfmId, String vnfId, String vimId, String onapCsarId, VnfScaleRequest request, String jobId) {
 
  80             com.nokia.cbam.lcm.v32.model.VnfInfo vnf = cbamRestApiProvider.getCbamLcmApi(vnfmId).vnfsVnfInstanceIdGet(vnfId, NOKIA_LCM_API_VERSION).blockingFirst();
 
  81             cbamVnfdId = vnf.getVnfdId();
 
  82         } catch (Exception e) {
 
  83             throw buildFatalFailure(logger, "Unable to query VNF " + vnfId, e);
 
  85         OperationType operationType = ScaleDirection.IN.equals(request.getType()) ? OperationType.SCALEIN : OperationType.SCALEOUT;
 
  86         GrantVNFRequest grantRequest = buildGrantRequest(vnfmId, vimId, onapCsarId, jobId, operationType);
 
  87         String vnfdContent = catalogManager.getCbamVnfdContent(vnfmId, cbamVnfdId);
 
  88         Set<ResourceChange> resourceChanges = calculateResourceChangeDuringScaling(vnfdContent, request.getAspectId(), Integer.parseInt(request.getNumberOfSteps()));
 
  89         if (request.getType() == ScaleDirection.IN) {
 
  90             grantRequest.getRemoveResource().addAll(resourceChanges);
 
  93             grantRequest.getAddResource().addAll(resourceChanges);
 
  95         grantRequest.setVnfInstanceId(vnfId);
 
  96         requestGrant(grantRequest);
 
 100     public void requestGrantForTerminate(String vnfmId, String vnfId, String vimId, String onapVnfdId, VnfInfo vnf, String jobId) {
 
 101         if (vnf.getInstantiationState() == INSTANTIATED) {
 
 102             GrantVNFRequest grantRequest;
 
 104                 grantRequest = buildGrantRequest(vnfmId, vimId, onapVnfdId, jobId, TERMINAL);
 
 105                 grantRequest.setVnfInstanceId(vnfId);
 
 106                 addVnfcsToGrant(vnf, grantRequest);
 
 107             } catch (Exception e) {
 
 108                 throw buildFatalFailure(logger, "Unable to prepare grant request for termination", e);
 
 110             requestGrant(grantRequest);
 
 114     private void addVnfcsToGrant(VnfInfo vnf, GrantVNFRequest grantRequest) {
 
 115         //VNF is instantiated but has no VNFC
 
 116         if (vnf.getInstantiatedVnfInfo().getVnfcResourceInfo() != null) {
 
 117             for (VnfcResourceInfo vnfc : vnf.getInstantiatedVnfInfo().getVnfcResourceInfo()) {
 
 118                 ResourceChange resourceChange = new ResourceChange();
 
 119                 grantRequest.getRemoveResource().add(resourceChange);
 
 120                 resourceChange.setVdu(vnfc.getVduId());
 
 121                 resourceChange.setType(ChangeType.VDU);
 
 122                 resourceChange.setResourceDefinitionId(UUID.randomUUID().toString());
 
 128     public GrantVNFResponseVim requestGrantForInstantiate(String vnfmId, String vnfId, String vimId, String onapVnfdId, String instantiationLevelId, String cbamVnfdContent, String jobId) {
 
 129         GrantVNFRequest grantRequest;
 
 131             grantRequest = buildGrantRequest(vnfmId, vimId, onapVnfdId, jobId, OperationType.INSTANTIATE);
 
 132             grantRequest.setVnfInstanceId(vnfId);
 
 133             grantRequest.setAddResource(new ArrayList<>());
 
 134             grantRequest.getAddResource().addAll(calculateResourceChangeDuringInstantiate(cbamVnfdContent, instantiationLevelId));
 
 135         } catch (Exception e) {
 
 136             throw buildFatalFailure(logger, "Unable to prepare grant request for instantiation", e);
 
 138         return requestGrant(grantRequest);
 
 141     private GrantVNFRequest buildGrantRequest(String vnfmId, String vimId, String onapCsarId, String jobId, OperationType operationType) {
 
 142         GrantVNFRequest grantVNFRequest = new GrantVNFRequest();
 
 144         //Currently the grant request sent to VF-C must contain the VIM identifier in the
 
 145         //grant response (normally in ETSI VIM identifier is received in the grant response
 
 146         //from ETSI orchestrator the vimId parameter should be removed from this POJO
 
 147         //to be able to fix this https://jira.onap.org/browse/VFC-603 must be solved
 
 148         //the vimId should be removed from the AdditionalGrantParams structure
 
 149         grantVNFRequest.setAdditionalParam(new AdditionalGrantParams(vnfmId, vimId));
 
 150         grantVNFRequest.setVnfDescriptorId(onapCsarId);
 
 151         grantVNFRequest.setJobId(jobId);
 
 152         grantVNFRequest.setLifecycleOperation(operationType);
 
 153         grantVNFRequest.setAddResource(new ArrayList<>());
 
 154         grantVNFRequest.setRemoveResource(new ArrayList<>());
 
 155         return grantVNFRequest;
 
 158     private GrantVNFResponseVim requestGrant(GrantVNFRequest grantRequest) {
 
 160             return vfcRestApiProvider.getNsLcmApi().grantvnf(grantRequest).execute().body().getVim();
 
 161         } catch (Exception e) {
 
 162             throw buildFatalFailure(logger, "Unable to request grant", e);
 
 166     private Set<ResourceChange> calculateResourceChangeDuringInstantiate(String vnfdContent, String instantiationLevelId) {
 
 167         JsonObject root = new Gson().toJsonTree(new Yaml().load(vnfdContent)).getAsJsonObject();
 
 168         JsonObject capabilities = child(child(child(root, "topology_template"), "substitution_mappings"), "capabilities");
 
 169         JsonObject deploymentFlavorProperties = child(child(capabilities, "deployment_flavour"), "properties");
 
 170         JsonObject instantiationLevels = child(deploymentFlavorProperties, "instantiation_levels");
 
 171         Set<ResourceChange> resourceChanges = new HashSet<>();
 
 172         for (Map.Entry<String, JsonElement> vdu_level : child(child(instantiationLevels, instantiationLevelId), ("vdu_levels")).entrySet()) {
 
 173             JsonElement numberOfInstances = vdu_level.getValue().getAsJsonObject().get("number_of_instances");
 
 174             for (int i = 0; i < numberOfInstances.getAsLong(); i++) {
 
 175                 ResourceChange resourceChange = new ResourceChange();
 
 176                 resourceChanges.add(resourceChange);
 
 177                 resourceChange.setVdu(vdu_level.getKey());
 
 178                 resourceChange.setType(ChangeType.VDU);
 
 179                 resourceChange.setResourceDefinitionId(UUID.randomUUID().toString());
 
 182         return resourceChanges;
 
 185     private Set<ResourceChange> calculateResourceChangeDuringScaling(String vnfdContent, String aspectId, int steps) {
 
 186         JsonObject root = new Gson().toJsonTree(new Yaml().load(vnfdContent)).getAsJsonObject();
 
 187         Set<ResourceChange> resourceChanges = new HashSet<>();
 
 188         JsonArray policies = child(root, "topology_template").getAsJsonObject().get("policies").getAsJsonArray();
 
 189         for (JsonElement policy : policies) {
 
 190             if ("heat_mapping".equals(policy.getAsJsonObject().entrySet().iterator().next().getKey())) {
 
 191                 JsonObject aspects = policy.getAsJsonObject().entrySet().iterator().next().getValue().getAsJsonObject().get("properties").getAsJsonObject().get("aspects").getAsJsonObject();
 
 192                 JsonObject aspect = child(aspects, aspectId);
 
 193                 if (aspect.has("vdus")) {
 
 194                     addChangesForAspect(steps, resourceChanges, aspect);
 
 198         return resourceChanges;
 
 201     private void addChangesForAspect(int steps, Set<ResourceChange> resourceChanges, JsonObject aspect) {
 
 202         for (Map.Entry<String, JsonElement> vdu : aspect.get("vdus").getAsJsonObject().entrySet()) {
 
 203             String vduId = vdu.getKey();
 
 204             for (int step = 0; step < steps; step++) {
 
 205                 for (int i = 0; i < vdu.getValue().getAsJsonArray().size(); i++) {
 
 206                     ResourceChange resourceChange = new ResourceChange();
 
 207                     resourceChange.setVdu(vduId);
 
 208                     resourceChange.setType(ChangeType.VDU);
 
 209                     resourceChange.setResourceDefinitionId(UUID.randomUUID().toString());
 
 210                     resourceChanges.add(resourceChange);
 
 217      * Represents the mandatory parameters that must be sent during grant request to VF-C
 
 220     static class AdditionalGrantParams {
 
 221         private final String vnfmId;
 
 222         private final String vimId;
 
 224         AdditionalGrantParams(String vnfmId, String vimId) {
 
 225             this.vnfmId = vnfmId;
 
 230          * @return the identifier of the VNFM requesting the grant
 
 232         public String getVnfmId() {
 
 237          * @return the identifier of the VIM for which the grant is requested
 
 239         public String getVimId() {