@Override
  public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
    s_logger.info("Configure VmwareManagerImpl, manager name: " + name);

    _name = name;

    ComponentLocator locator = ComponentLocator.getCurrentLocator();
    ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
    if (configDao == null) {
      throw new ConfigurationException("Unable to get the configuration dao.");
    }

    if (!configDao.isPremium()) {
      s_logger.error("Vmware component can only run under premium distribution");
      throw new ConfigurationException("Vmware component can only run under premium distribution");
    }

    _instance = configDao.getValue(Config.InstanceName.key());
    if (_instance == null) {
      _instance = "DEFAULT";
    }
    s_logger.info("VmwareManagerImpl config - instance.name: " + _instance);

    _mountParent = configDao.getValue(Config.MountParent.key());
    if (_mountParent == null) {
      _mountParent = File.separator + "mnt";
    }

    if (_instance != null) {
      _mountParent = _mountParent + File.separator + _instance;
    }
    s_logger.info("VmwareManagerImpl config - _mountParent: " + _mountParent);

    String value = (String) params.get("scripts.timeout");
    _timeout = NumbersUtil.parseInt(value, 1440) * 1000;

    _storage = (StorageLayer) params.get(StorageLayer.InstanceConfigKey);
    if (_storage == null) {
      value = (String) params.get(StorageLayer.ClassConfigKey);
      if (value == null) {
        value = "com.cloud.storage.JavaStorageLayer";
      }

      try {
        Class<?> clazz = Class.forName(value);
        _storage = (StorageLayer) ComponentLocator.inject(clazz);
        _storage.configure("StorageLayer", params);
      } catch (ClassNotFoundException e) {
        throw new ConfigurationException("Unable to find class " + value);
      }
    }

    _privateNetworkVSwitchName = configDao.getValue(Config.VmwarePrivateNetworkVSwitch.key());
    if (_privateNetworkVSwitchName == null) {
      _privateNetworkVSwitchName = "vSwitch0";
    }

    _publicNetworkVSwitchName = configDao.getValue(Config.VmwarePublicNetworkVSwitch.key());
    if (_publicNetworkVSwitchName == null) {
      _publicNetworkVSwitchName = "vSwitch0";
    }

    _guestNetworkVSwitchName = configDao.getValue(Config.VmwareGuestNetworkVSwitch.key());
    if (_guestNetworkVSwitchName == null) {
      _guestNetworkVSwitchName = "vSwitch0";
    }

    _serviceConsoleName = configDao.getValue(Config.VmwareServiceConsole.key());
    if (_serviceConsoleName == null) {
      _serviceConsoleName = "Service Console";
    }

    _managemetPortGroupName = configDao.getValue(Config.VmwareManagementPortGroup.key());
    if (_managemetPortGroupName == null) {
      _managemetPortGroupName = "Management Network";
    }

    configDao.getValue(Config.VmwareServiceConsole.key());
    _additionalPortRangeStart =
        NumbersUtil.parseInt(
            configDao.getValue(Config.VmwareAdditionalVncPortRangeStart.key()), 59000);
    if (_additionalPortRangeStart > 65535) {
      s_logger.warn(
          "Invalid port range start port ("
              + _additionalPortRangeStart
              + ") for additional VNC port allocation, reset it to default start port 59000");
      _additionalPortRangeStart = 59000;
    }

    _additionalPortRangeSize =
        NumbersUtil.parseInt(
            configDao.getValue(Config.VmwareAdditionalVncPortRangeSize.key()), 1000);
    if (_additionalPortRangeSize < 0
        || _additionalPortRangeStart + _additionalPortRangeSize > 65535) {
      s_logger.warn(
          "Invalid port range size ("
              + _additionalPortRangeSize
              + " for range starts at "
              + _additionalPortRangeStart);
      _additionalPortRangeSize = Math.min(1000, 65535 - _additionalPortRangeStart);
    }

    _maxHostsPerCluster =
        NumbersUtil.parseInt(
            configDao.getValue(Config.VmwarePerClusterHostMax.key()),
            VmwareManager.MAX_HOSTS_PER_CLUSTER);
    _cpuOverprovisioningFactor = configDao.getValue(Config.CPUOverprovisioningFactor.key());
    if (_cpuOverprovisioningFactor == null || _cpuOverprovisioningFactor.isEmpty())
      _cpuOverprovisioningFactor = "1";

    _memOverprovisioningFactor = configDao.getValue(Config.MemOverprovisioningFactor.key());
    if (_memOverprovisioningFactor == null || _memOverprovisioningFactor.isEmpty())
      _memOverprovisioningFactor = "1";

    _reserveCpu = configDao.getValue(Config.VmwareReserveCpu.key());
    if (_reserveCpu == null || _reserveCpu.isEmpty()) _reserveCpu = "false";
    _reserveMem = configDao.getValue(Config.VmwareReserveMem.key());
    if (_reserveMem == null || _reserveMem.isEmpty()) _reserveMem = "false";

    s_logger.info(
        "Additional VNC port allocation range is settled at "
            + _additionalPortRangeStart
            + " to "
            + (_additionalPortRangeStart + _additionalPortRangeSize));

    value = configDao.getValue(Config.VmwareGuestNicDeviceType.key());
    if (value == null || "E1000".equalsIgnoreCase(value))
      this._guestNicDeviceType = VirtualEthernetCardType.E1000;
    else if ("PCNet32".equalsIgnoreCase(value))
      this._guestNicDeviceType = VirtualEthernetCardType.PCNet32;
    else if ("Vmxnet2".equalsIgnoreCase(value))
      this._guestNicDeviceType = VirtualEthernetCardType.Vmxnet2;
    else if ("Vmxnet3".equalsIgnoreCase(value))
      this._guestNicDeviceType = VirtualEthernetCardType.Vmxnet3;
    else this._guestNicDeviceType = VirtualEthernetCardType.E1000;

    value = configDao.getValue("vmware.host.scan.interval");
    _hostScanInterval = NumbersUtil.parseLong(value, DEFAULT_HOST_SCAN_INTERVAL);
    s_logger.info("VmwareManagerImpl config - vmware.host.scan.interval: " + _hostScanInterval);

    ((VmwareStorageManagerImpl) _storageMgr).configure(params);

    _agentMgr.registerForHostEvents(this, true, true, true);

    s_logger.info("VmwareManagerImpl has been successfully configured");
    return true;
  }
  @Override
  public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
    s_logger.info("Configure VmwareManagerImpl, manager name: " + name);

    if (!_configDao.isPremium()) {
      s_logger.error("Vmware component can only run under premium distribution");
      throw new ConfigurationException("Vmware component can only run under premium distribution");
    }

    _instance = _configDao.getValue(Config.InstanceName.key());
    if (_instance == null) {
      _instance = "DEFAULT";
    }
    s_logger.info("VmwareManagerImpl config - instance.name: " + _instance);

    _mountParent = _configDao.getValue(Config.MountParent.key());
    if (_mountParent == null) {
      _mountParent = File.separator + "mnt";
    }

    if (_instance != null) {
      _mountParent = _mountParent + File.separator + _instance;
    }
    s_logger.info("VmwareManagerImpl config - _mountParent: " + _mountParent);

    String value = (String) params.get("scripts.timeout");
    _timeout = NumbersUtil.parseInt(value, 1440) * 1000;

    _storage = (StorageLayer) params.get(StorageLayer.InstanceConfigKey);
    if (_storage == null) {
      _storage = new JavaStorageLayer();
      _storage.configure("StorageLayer", params);
    }

    value = _configDao.getValue(Config.VmwareCreateFullClone.key());
    if (value == null) {
      _fullCloneFlag = false;
    } else {
      _fullCloneFlag = Boolean.parseBoolean(value);
    }
    _portsPerDvPortGroup =
        NumbersUtil.parseInt(
            _configDao.getValue(Config.VmwarePortsPerDVPortGroup.key()), _portsPerDvPortGroup);

    _serviceConsoleName = _configDao.getValue(Config.VmwareServiceConsole.key());
    if (_serviceConsoleName == null) {
      _serviceConsoleName = "Service Console";
    }

    _managemetPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
    if (_managemetPortGroupName == null) {
      _managemetPortGroupName = "Management Network";
    }

    _defaultSystemVmNicAdapterType = _configDao.getValue(Config.VmwareSystemVmNicDeviceType.key());
    if (_defaultSystemVmNicAdapterType == null) {
      _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
    }

    _additionalPortRangeStart =
        NumbersUtil.parseInt(
            _configDao.getValue(Config.VmwareAdditionalVncPortRangeStart.key()), 59000);
    if (_additionalPortRangeStart > 65535) {
      s_logger.warn(
          "Invalid port range start port ("
              + _additionalPortRangeStart
              + ") for additional VNC port allocation, reset it to default start port 59000");
      _additionalPortRangeStart = 59000;
    }

    _additionalPortRangeSize =
        NumbersUtil.parseInt(
            _configDao.getValue(Config.VmwareAdditionalVncPortRangeSize.key()), 1000);
    if (_additionalPortRangeSize < 0
        || _additionalPortRangeStart + _additionalPortRangeSize > 65535) {
      s_logger.warn(
          "Invalid port range size ("
              + _additionalPortRangeSize
              + " for range starts at "
              + _additionalPortRangeStart);
      _additionalPortRangeSize = Math.min(1000, 65535 - _additionalPortRangeStart);
    }

    _routerExtraPublicNics =
        NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2);

    _reserveCpu = _configDao.getValue(Config.VmwareReserveCpu.key());
    if (_reserveCpu == null || _reserveCpu.isEmpty()) {
      _reserveCpu = "false";
    }
    _reserveMem = _configDao.getValue(Config.VmwareReserveMem.key());
    if (_reserveMem == null || _reserveMem.isEmpty()) {
      _reserveMem = "false";
    }

    _recycleHungWorker = _configDao.getValue(Config.VmwareRecycleHungWorker.key());
    if (_recycleHungWorker == null || _recycleHungWorker.isEmpty()) {
      _recycleHungWorker = "false";
    }

    _rootDiskController = _configDao.getValue(Config.VmwareRootDiskControllerType.key());
    if (_rootDiskController == null || _rootDiskController.isEmpty()) {
      _rootDiskController = DiskControllerType.ide.toString();
    }

    s_logger.info(
        "Additional VNC port allocation range is settled at "
            + _additionalPortRangeStart
            + " to "
            + (_additionalPortRangeStart + _additionalPortRangeSize));

    value = _configDao.getValue("vmware.host.scan.interval");
    _hostScanInterval = NumbersUtil.parseLong(value, DEFAULT_HOST_SCAN_INTERVAL);
    s_logger.info("VmwareManagerImpl config - vmware.host.scan.interval: " + _hostScanInterval);

    ((VmwareStorageManagerImpl) _storageMgr).configure(params);

    _agentMgr.registerForHostEvents(this, true, true, true);

    s_logger.info("VmwareManagerImpl has been successfully configured");
    return true;
  }
  @Override
  public boolean finalizeVirtualMachineProfile(
      VirtualMachineProfile<SecondaryStorageVmVO> profile,
      DeployDestination dest,
      ReservationContext context) {

    SecondaryStorageVmVO vm = profile.getVirtualMachine();
    Map<String, String> details = _vmDetailsDao.findDetails(vm.getId());
    vm.setDetails(details);

    HostVO secHost = _hostDao.findSecondaryStorageHost(dest.getDataCenter().getId());
    assert (secHost != null);

    StringBuilder buf = profile.getBootArgsBuilder();
    buf.append(" template=domP type=secstorage");
    buf.append(" host=").append(_mgmt_host);
    buf.append(" port=").append(_mgmt_port);
    buf.append(" name=").append(profile.getVirtualMachine().getHostName());

    buf.append(" zone=").append(dest.getDataCenter().getId());
    buf.append(" pod=").append(dest.getPod().getId());

    buf.append(" guid=").append(profile.getVirtualMachine().getHostName());

    if (_configDao.isPremium()) {
      if (profile.getHypervisorType() == HypervisorType.Hyperv) {
        buf.append(" resource=com.cloud.storage.resource.CifsSecondaryStorageResource");
      } else {
        buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
      }
    } else {
      buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource");
    }
    buf.append(" instance=SecStorage");
    buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
    buf.append(" role=").append(profile.getVirtualMachine().getRole().toString());

    boolean externalDhcp = false;
    String externalDhcpStr =
        _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
    if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
      externalDhcp = true;
    }

    for (NicProfile nic : profile.getNics()) {
      int deviceId = nic.getDeviceId();
      if (nic.getIp4Address() == null) {
        buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
        buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
      } else {
        buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address());
        buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
      }

      buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
      if (nic.isDefaultNic()) {
        buf.append(" gateway=").append(nic.getGateway());
      }
      if (nic.getTrafficType() == TrafficType.Management) {
        String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
        if (NetUtils.isValidCIDR(mgmt_cidr)) {
          buf.append(" mgmtcidr=").append(mgmt_cidr);
        }
        buf.append(" localgw=").append(dest.getPod().getGateway());
        buf.append(" private.network.device=").append("eth").append(deviceId);
      } else if (nic.getTrafficType() == TrafficType.Public) {
        buf.append(" public.network.device=").append("eth").append(deviceId);
      }
    }

    /* External DHCP mode */
    if (externalDhcp) {
      buf.append(" bootproto=dhcp");
    }

    DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterIdToDeployIn());
    buf.append(" internaldns1=").append(dc.getInternalDns1());
    if (dc.getInternalDns2() != null) {
      buf.append(" internaldns2=").append(dc.getInternalDns2());
    }
    buf.append(" dns1=").append(dc.getDns1());
    if (dc.getDns2() != null) {
      buf.append(" dns2=").append(dc.getDns2());
    }

    String bootArgs = buf.toString();
    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
    }

    return true;
  }