All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openbaton.common.vnfm_sdk.AbstractVnfm Maven / Gradle / Ivy

There is a newer version: 6.0.0
Show newest version
/*
 * Copyright (c) 2016 Open Baton (http://www.openbaton.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package org.openbaton.common.vnfm_sdk;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.openbaton.catalogue.mano.descriptor.InternalVirtualLink;
import org.openbaton.catalogue.mano.descriptor.VNFComponent;
import org.openbaton.catalogue.mano.descriptor.VirtualDeploymentUnit;
import org.openbaton.catalogue.mano.descriptor.VirtualNetworkFunctionDescriptor;
import org.openbaton.catalogue.mano.record.VNFCInstance;
import org.openbaton.catalogue.mano.record.VNFRecordDependency;
import org.openbaton.catalogue.mano.record.VirtualLinkRecord;
import org.openbaton.catalogue.mano.record.VirtualNetworkFunctionRecord;
import org.openbaton.catalogue.nfvo.Action;
import org.openbaton.catalogue.nfvo.Script;
import org.openbaton.catalogue.nfvo.VnfmManagerEndpoint;
import org.openbaton.catalogue.nfvo.messages.*;
import org.openbaton.catalogue.nfvo.messages.Interfaces.NFVMessage;
import org.openbaton.catalogue.nfvo.viminstances.BaseVimInstance;
import org.openbaton.catalogue.security.Key;
import org.openbaton.common.vnfm_sdk.exception.BadFormatException;
import org.openbaton.common.vnfm_sdk.exception.NotFoundException;
import org.openbaton.common.vnfm_sdk.exception.VnfmSdkException;
import org.openbaton.common.vnfm_sdk.interfaces.LogDispatcher;
import org.openbaton.common.vnfm_sdk.interfaces.VNFLifecycleChangeNotification;
import org.openbaton.common.vnfm_sdk.interfaces.VNFLifecycleManagement;
import org.openbaton.common.vnfm_sdk.utils.VNFRUtils;
import org.openbaton.common.vnfm_sdk.utils.VnfmUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Created by lto on 08/07/15. */
public abstract class AbstractVnfm
    implements VNFLifecycleManagement, VNFLifecycleChangeNotification {

  protected static String type;
  protected static String endpoint;
  protected static String endpointType;
  protected static Properties properties;
  protected static Logger log = LoggerFactory.getLogger(AbstractVnfm.class);
  protected VnfmHelper vnfmHelper;
  protected VnfmManagerEndpoint vnfmManagerEndpoint;
  private ExecutorService executor;
  protected static String brokerIp;
  protected static String brokerPort;
  protected static String monitoringIp;
  protected static String timezone;
  protected static String username;
  protected static String password;
  protected static String exchangeName;
  protected static String nsrId;

  public boolean isEnabled() {
    return enabled;
  }

  public void setEnabled(boolean enabled) {
    this.enabled = enabled;
  }

  private boolean enabled;

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  private String description;

  // If the VNFM supports the requesting of log files, it can instantiate this field (e.g. in the setup method), otherwise it will not be used.
  protected LogDispatcher logDispatcher;

  @PreDestroy
  private void shutdown() {}

  @PostConstruct
  private void init() {
    setup();
    executor =
        Executors.newFixedThreadPool(Integer.parseInt(properties.getProperty("concurrency", "15")));
  }

  public String getType() {
    return type;
  }

  public void setType(String type) {
    this.type = type;
  }

  public String getEndpoint() {
    return endpoint;
  }

  public void setEndpoint(String endpoint) {
    this.endpoint = endpoint;
  }

  public Properties getProperties() {
    return properties;
  }

  public void setProperties(Properties properties) {
    this.properties = properties;
  }

  @Override
  public abstract void query();

  @Override
  public abstract VirtualNetworkFunctionRecord scale(
      Action scaleInOrOut,
      VirtualNetworkFunctionRecord virtualNetworkFunctionRecord,
      VNFComponent component,
      Object scripts,
      VNFRecordDependency dependency)
      throws Exception;

  @Override
  public abstract void checkInstantiationFeasibility();

  @Override
  public abstract VirtualNetworkFunctionRecord heal(
      VirtualNetworkFunctionRecord virtualNetworkFunctionRecord,
      VNFCInstance component,
      String cause)
      throws Exception;

  @Override
  public abstract VirtualNetworkFunctionRecord updateSoftware(
      Script script, VirtualNetworkFunctionRecord virtualNetworkFunctionRecord) throws Exception;

  @Override
  public abstract VirtualNetworkFunctionRecord modify(
      VirtualNetworkFunctionRecord virtualNetworkFunctionRecord, VNFRecordDependency dependency)
      throws Exception;

  @Override
  public abstract void upgradeSoftware();

  @Override
  public abstract VirtualNetworkFunctionRecord terminate(
      VirtualNetworkFunctionRecord virtualNetworkFunctionRecord) throws Exception;

  public abstract void handleError(VirtualNetworkFunctionRecord virtualNetworkFunctionRecord);

  protected void loadProperties() {
    properties = new Properties();
    try {
      properties.load(this.getClass().getClassLoader().getResourceAsStream("conf.properties"));
    } catch (IOException e) {
      e.printStackTrace();
      log.error(e.getLocalizedMessage());
    }
    endpoint = (String) properties.get("endpoint");
    type = (String) properties.get("type");
    endpointType = properties.getProperty("endpoint-type", "RABBIT");
    description = properties.getProperty("description", "");
    enabled = Boolean.parseBoolean(properties.getProperty("enabled", "true"));
  }

  protected NFVMessage onAction(NFVMessage message) throws NotFoundException, BadFormatException {

    VirtualNetworkFunctionRecord virtualNetworkFunctionRecord = null;

    try {
      log.debug(
          "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
              + message.getAction()
              + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
      log.trace("VNFM: Received Message: " + message.getAction());
      NFVMessage nfvMessage = null;
      OrVnfmGenericMessage orVnfmGenericMessage = null;
      switch (message.getAction()) {
        case SCALE_IN:
          OrVnfmScalingMessage scalingMessage = (OrVnfmScalingMessage) message;
          nsrId = scalingMessage.getVirtualNetworkFunctionRecord().getParent_ns_id();
          virtualNetworkFunctionRecord = scalingMessage.getVirtualNetworkFunctionRecord();
          VNFCInstance vnfcInstanceToRemove = scalingMessage.getVnfcInstance();

          virtualNetworkFunctionRecord =
              this.scale(
                  Action.SCALE_IN, virtualNetworkFunctionRecord, vnfcInstanceToRemove, null, null);
          nfvMessage = null;
          break;
        case SCALE_OUT:
          scalingMessage = (OrVnfmScalingMessage) message;
          // TODO I don't know if, using a bean of this class the instance can be destroyed and recreated and
          // parameters could be lost
          getExtension(scalingMessage.getExtension());

          nsrId = scalingMessage.getVirtualNetworkFunctionRecord().getParent_ns_id();
          virtualNetworkFunctionRecord = scalingMessage.getVirtualNetworkFunctionRecord();
          VNFRecordDependency dependency = scalingMessage.getDependency();
          VNFComponent component = scalingMessage.getComponent();
          String mode = scalingMessage.getMode();

          log.trace("HB_VERSION == " + virtualNetworkFunctionRecord.getHbVersion());
          log.info("Adding VNFComponent: " + component);
          log.trace("The mode is:" + mode);
          VNFCInstance vnfcInstance_new = null;
          if (!properties.getProperty("allocate", "true").equalsIgnoreCase("true")) {
            NFVMessage message2 =
                vnfmHelper.sendAndReceive(
                    VnfmUtils.getNfvScalingMessage(
                        getUserData(),
                        virtualNetworkFunctionRecord,
                        scalingMessage.getVimInstance()));
            if (message2 instanceof OrVnfmGenericMessage) {
              OrVnfmGenericMessage message1 = (OrVnfmGenericMessage) message2;
              virtualNetworkFunctionRecord = message1.getVnfr();
              log.trace("HB_VERSION == " + virtualNetworkFunctionRecord.getHbVersion());
            } else if (message2 instanceof OrVnfmErrorMessage) {
              this.handleError(((OrVnfmErrorMessage) message2).getVnfr());
              return null;
            }
            vnfcInstance_new = getVnfcInstance(virtualNetworkFunctionRecord, component);
            if (vnfcInstance_new == null) {
              throw new RuntimeException("no new VNFCInstance found. This should not happen...");
            }
            if (mode != null && mode.equalsIgnoreCase("standby")) {
              vnfcInstance_new.setState("STANDBY");
            }
          }

          Object scripts;
          if (scalingMessage.getVnfPackage() == null) {
            scripts = new HashSet<>();
          } else if (scalingMessage.getVnfPackage().getScriptsLink() != null) {
            scripts = scalingMessage.getVnfPackage().getScriptsLink();
          } else {
            scripts = scalingMessage.getVnfPackage().getScripts();
          }

          VirtualNetworkFunctionRecord vnfr =
              this.scale(
                  Action.SCALE_OUT,
                  virtualNetworkFunctionRecord,
                  vnfcInstance_new,
                  scripts,
                  dependency);
          if (vnfcInstance_new == null) {
            log.warn(
                "No new VNFCInstance found, either a bug or was not possible to instantiate it.");
          }
          nfvMessage = VnfmUtils.getNfvMessageScaled(Action.SCALED, vnfr, vnfcInstance_new);
          break;
        case SCALING:
          break;
        case ERROR:
          OrVnfmErrorMessage errorMessage = (OrVnfmErrorMessage) message;
          nsrId = errorMessage.getVnfr().getParent_ns_id();
          log.error("ERROR Received: " + errorMessage.getMessage());
          handleError(errorMessage.getVnfr());

          nfvMessage = null;
          break;
        case MODIFY:
          orVnfmGenericMessage = (OrVnfmGenericMessage) message;
          virtualNetworkFunctionRecord = orVnfmGenericMessage.getVnfr();
          nsrId = orVnfmGenericMessage.getVnfr().getParent_ns_id();
          nfvMessage =
              VnfmUtils.getNfvMessage(
                  Action.MODIFY,
                  this.modify(orVnfmGenericMessage.getVnfr(), orVnfmGenericMessage.getVnfrd()));
          break;
        case RELEASE_RESOURCES:
          orVnfmGenericMessage = (OrVnfmGenericMessage) message;
          nsrId = orVnfmGenericMessage.getVnfr().getParent_ns_id();
          virtualNetworkFunctionRecord = orVnfmGenericMessage.getVnfr();
          nfvMessage =
              VnfmUtils.getNfvMessage(
                  Action.RELEASE_RESOURCES, this.terminate(virtualNetworkFunctionRecord));
          break;
        case INSTANTIATE:
          OrVnfmInstantiateMessage orVnfmInstantiateMessage = (OrVnfmInstantiateMessage) message;
          Map extension = orVnfmInstantiateMessage.getExtension();

          log.debug("Extensions are: " + extension);
          log.debug("Keys are: " + orVnfmInstantiateMessage.getKeys());
          getExtension(extension);

          Map> vimInstances =
              orVnfmInstantiateMessage.getVimInstances();
          if (orVnfmInstantiateMessage.getVnfr() == null) {
            virtualNetworkFunctionRecord =
                createVirtualNetworkFunctionRecord(
                    orVnfmInstantiateMessage.getVnfd(),
                    orVnfmInstantiateMessage.getVnfdf().getFlavour_key(),
                    orVnfmInstantiateMessage.getVlrs(),
                    orVnfmInstantiateMessage.getExtension(),
                    vimInstances);

            log.trace("CREATE: HB VERSION IS: " + virtualNetworkFunctionRecord.getHbVersion());
            GrantOperation grantOperation = new GrantOperation();
            grantOperation.setVirtualNetworkFunctionRecord(virtualNetworkFunctionRecord);

            Future result = executor.submit(grantOperation);
            OrVnfmGrantLifecycleOperationMessage msg;
            try {
              msg = result.get();
              if (msg == null) {
                return null;
              }
            } catch (ExecutionException e) {
              log.error("Got exception while granting vms");
              throw e.getCause();
            }

            virtualNetworkFunctionRecord = msg.getVirtualNetworkFunctionRecord();
            Map vimInstanceChosen = msg.getVduVim();

            log.trace("GRANT: HB VERSION IS: " + virtualNetworkFunctionRecord.getHbVersion());

            if (!properties.getProperty("allocate", "true").equalsIgnoreCase("true")) {
              AllocateResources allocateResources = new AllocateResources();
              allocateResources.setVirtualNetworkFunctionRecord(virtualNetworkFunctionRecord);
              allocateResources.setVimInstances(vimInstanceChosen);
              allocateResources.setKeyPairs(orVnfmInstantiateMessage.getKeys());
              if (orVnfmInstantiateMessage.getVnfPackage() != null
                  && orVnfmInstantiateMessage.getVnfPackage().getScripts() != null)
                allocateResources.setCustomUserData(
                    getUserDataFromPackage(orVnfmInstantiateMessage.getVnfPackage().getScripts()));
              try {
                virtualNetworkFunctionRecord = executor.submit(allocateResources).get();
                if (virtualNetworkFunctionRecord == null) {
                  return null;
                }
              } catch (ExecutionException e) {
                log.error("Got exception while allocating vms");
                throw e.getCause();
              }
            }
            log.trace("ALLOCATE: HB VERSION IS: " + virtualNetworkFunctionRecord.getHbVersion());
            setupProvides(virtualNetworkFunctionRecord);
          } else virtualNetworkFunctionRecord = orVnfmInstantiateMessage.getVnfr();
          if (orVnfmInstantiateMessage.getVnfPackage() != null) {
            if (orVnfmInstantiateMessage.getVnfPackage().getScriptsLink() != null) {
              virtualNetworkFunctionRecord =
                  instantiate(
                      virtualNetworkFunctionRecord,
                      orVnfmInstantiateMessage.getVnfPackage().getScriptsLink(),
                      vimInstances);
            } else {
              virtualNetworkFunctionRecord =
                  instantiate(
                      virtualNetworkFunctionRecord,
                      orVnfmInstantiateMessage.getVnfPackage().getScripts(),
                      vimInstances);
            }
          } else {
            virtualNetworkFunctionRecord =
                instantiate(virtualNetworkFunctionRecord, null, vimInstances);
          }
          nfvMessage = VnfmUtils.getNfvMessage(Action.INSTANTIATE, virtualNetworkFunctionRecord);
          break;
        case RELEASE_RESOURCES_FINISH:
          break;
        case UPDATE:
          OrVnfmUpdateMessage orVnfmUpdateMessage = (OrVnfmUpdateMessage) message;
          nfvMessage =
              VnfmUtils.getNfvMessage(
                  Action.UPDATE,
                  updateSoftware(orVnfmUpdateMessage.getScript(), orVnfmUpdateMessage.getVnfr()));
          break;
        case HEAL:
          OrVnfmHealVNFRequestMessage orVnfmHealMessage = (OrVnfmHealVNFRequestMessage) message;

          nsrId = orVnfmHealMessage.getVirtualNetworkFunctionRecord().getParent_ns_id();
          VirtualNetworkFunctionRecord vnfrObtained =
              this.heal(
                  orVnfmHealMessage.getVirtualNetworkFunctionRecord(),
                  orVnfmHealMessage.getVnfcInstance(),
                  orVnfmHealMessage.getCause());
          nfvMessage =
              VnfmUtils.getNfvMessageHealed(
                  Action.HEAL, vnfrObtained, orVnfmHealMessage.getVnfcInstance());

          break;
        case INSTANTIATE_FINISH:
          break;
        case CONFIGURE:
          orVnfmGenericMessage = (OrVnfmGenericMessage) message;
          virtualNetworkFunctionRecord = orVnfmGenericMessage.getVnfr();
          nsrId = orVnfmGenericMessage.getVnfr().getParent_ns_id();
          nfvMessage =
              VnfmUtils.getNfvMessage(Action.CONFIGURE, configure(orVnfmGenericMessage.getVnfr()));
          break;
        case START:
          {
            OrVnfmStartStopMessage orVnfmStartStopMessage = (OrVnfmStartStopMessage) message;
            virtualNetworkFunctionRecord = orVnfmStartStopMessage.getVirtualNetworkFunctionRecord();
            nsrId = virtualNetworkFunctionRecord.getParent_ns_id();
            VNFCInstance vnfcInstance = orVnfmStartStopMessage.getVnfcInstance();

            if (vnfcInstance == null) // Start the VNF Record
            {
              nfvMessage =
                  VnfmUtils.getNfvMessage(Action.START, start(virtualNetworkFunctionRecord));
            } else // Start the VNFC Instance
            {
              nfvMessage =
                  VnfmUtils.getNfvMessageStartStop(
                      Action.START,
                      startVNFCInstance(virtualNetworkFunctionRecord, vnfcInstance),
                      vnfcInstance);
            }
            break;
          }
        case STOP:
          {
            OrVnfmStartStopMessage orVnfmStartStopMessage = (OrVnfmStartStopMessage) message;
            virtualNetworkFunctionRecord = orVnfmStartStopMessage.getVirtualNetworkFunctionRecord();
            nsrId = virtualNetworkFunctionRecord.getParent_ns_id();
            VNFCInstance vnfcInstance = orVnfmStartStopMessage.getVnfcInstance();

            if (vnfcInstance == null) // Stop the VNF Record
            {
              nfvMessage = VnfmUtils.getNfvMessage(Action.STOP, stop(virtualNetworkFunctionRecord));
            } else // Stop the VNFC Instance
            {
              nfvMessage =
                  VnfmUtils.getNfvMessageStartStop(
                      Action.STOP,
                      stopVNFCInstance(virtualNetworkFunctionRecord, vnfcInstance),
                      vnfcInstance);
            }

            break;
          }
        case RESUME:
          {
            OrVnfmGenericMessage orVnfmResumeMessage = (OrVnfmGenericMessage) message;
            virtualNetworkFunctionRecord = orVnfmResumeMessage.getVnfr();
            nsrId = virtualNetworkFunctionRecord.getParent_ns_id();

            Action resumedAction = this.getResumedAction(virtualNetworkFunctionRecord, null);
            if (orVnfmResumeMessage.getVnfrd() == null) {
              log.debug(
                  "Resuming vnfr '"
                      + virtualNetworkFunctionRecord.getId()
                      + "' for action: "
                      + resumedAction
                      + "'");
            } else {
              log.debug(
                  "Resuming vnfr '"
                      + virtualNetworkFunctionRecord.getId()
                      + "' with dependency target: '"
                      + orVnfmResumeMessage.getVnfrd().getTarget()
                      + "' for action: "
                      + resumedAction
                      + "'");
            }
            // to prevent a VNFM, that does not implement resume, from throwing Null Pointer Exception.
            if (resumedAction == null) {
              resumedAction = Action.ERROR;
            }
            nfvMessage =
                VnfmUtils.getNfvMessage(
                    resumedAction,
                    resume(virtualNetworkFunctionRecord, null, orVnfmResumeMessage.getVnfrd()));

            break;
          }
        case EXECUTE:
          {
            OrVnfmExecuteScriptMessage orVnfmExecuteMessage = (OrVnfmExecuteScriptMessage) message;
            nfvMessage =
                VnfmUtils.getNfvMessage(
                    Action.EXECUTE,
                    executeScript(
                        orVnfmExecuteMessage.getVnfr(), orVnfmExecuteMessage.getScript()));
            break;
          }
        case LOG_REQUEST:
          {
            OrVnfmLogMessage orVnfmLogMessage = (OrVnfmLogMessage) message;
            // if the VNFM does not support log requests (i.e. no LogDispatcher is implemented), it will return a default "error" OrVnfmLogMessage
            if (logDispatcher != null) {
              nfvMessage = new VnfmOrLogMessage();
              nfvMessage = logDispatcher.getLogs(orVnfmLogMessage);
            } else {
              List errorList = new LinkedList<>();
              errorList.add("This VNFM does not support the requesting of log files.");
              nfvMessage = new VnfmOrLogMessage(new LinkedList(), errorList);
            }
          }
      }

      log.debug(
          "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
      if (nfvMessage != null) {
        return nfvMessage;
      }
    } catch (Throwable e) {
      log.error("ERROR: ", e);
      if (e instanceof VnfmSdkException) {
        VnfmSdkException vnfmSdkException = (VnfmSdkException) e;
        if (vnfmSdkException.getVnfr() != null) {
          log.debug("sending VNFR with version: " + vnfmSdkException.getVnfr().getHbVersion());
          return VnfmUtils.getNfvErrorMessage(vnfmSdkException.getVnfr(), vnfmSdkException, nsrId);
        }
      } else if (e.getCause() instanceof VnfmSdkException) {
        VnfmSdkException vnfmSdkException = (VnfmSdkException) e.getCause();
        if (vnfmSdkException.getVnfr() != null) {
          log.debug("sending VNFR with version: " + vnfmSdkException.getVnfr().getHbVersion());
          return VnfmUtils.getNfvErrorMessage(vnfmSdkException.getVnfr(), vnfmSdkException, nsrId);
        }
      }
      return VnfmUtils.getNfvErrorMessage(virtualNetworkFunctionRecord, e, nsrId);
    }
    return null;
  }

  private String getUserDataFromPackage(Set