// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you 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 com.cloud.hypervisor.vmware.mo; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.log4j.Logger; import com.vmware.vim25.DVPortgroupConfigSpec; import com.vmware.vim25.DVSConfigInfo; import com.vmware.vim25.ManagedObjectReference; import com.vmware.vim25.TaskInfo; import com.vmware.vim25.VMwareDVSConfigInfo; import com.vmware.vim25.VMwareDVSConfigSpec; import com.vmware.vim25.VMwareDVSPvlanMapEntry; import com.cloud.hypervisor.vmware.util.VmwareContext; public class DistributedVirtualSwitchMO extends BaseMO { @SuppressWarnings("unused") private static final Logger s_logger = Logger.getLogger(DistributedVirtualSwitchMO.class); private static ConcurrentHashMap> s_dvPortGroupCacheMap = null; public DistributedVirtualSwitchMO(VmwareContext context, ManagedObjectReference morDvs) { super(context, morDvs); s_dvPortGroupCacheMap = new ConcurrentHashMap>(); } public DistributedVirtualSwitchMO(VmwareContext context, String morType, String morValue) { super(context, morType, morValue); s_dvPortGroupCacheMap = new ConcurrentHashMap>(); } public void createDVPortGroup(DVPortgroupConfigSpec dvPortGroupSpec) throws Exception { List dvPortGroupSpecArray = new ArrayList(); dvPortGroupSpecArray.add(dvPortGroupSpec); boolean dvPortGroupExists = false; String dvSwitchInstance = _mor.getValue(); String dvPortGroupName = dvPortGroupSpec.getName(); String uniquedvPortGroupPerDvs = dvSwitchInstance + dvPortGroupName; List dvPortGroupList = null; synchronized (uniquedvPortGroupPerDvs.intern()) { // Looking up local cache rather than firing another API call to see if dvPortGroup exists already. if (s_dvPortGroupCacheMap.containsKey(dvSwitchInstance)) { dvPortGroupList = s_dvPortGroupCacheMap.get(dvSwitchInstance); if (dvPortGroupList != null && dvPortGroupList.contains(dvPortGroupName)) { dvPortGroupExists = true; } } if (!dvPortGroupExists) { ManagedObjectReference task = _context.getService().addDVPortgroupTask(_mor, dvPortGroupSpecArray); if (!_context.getVimClient().waitForTask(task)) { throw new Exception("Failed to create dvPortGroup " + dvPortGroupSpec.getName()); } else { if (s_dvPortGroupCacheMap.containsKey(dvSwitchInstance)) { dvPortGroupList = s_dvPortGroupCacheMap.get(dvSwitchInstance); if (dvPortGroupList == null) { dvPortGroupList = new ArrayList(); } dvPortGroupList.add(dvPortGroupName); //does this update map? } else { dvPortGroupList = new ArrayList(); dvPortGroupList.add(dvPortGroupName); s_dvPortGroupCacheMap.put(dvSwitchInstance, dvPortGroupList); } } if (s_logger.isTraceEnabled()) { s_logger.trace("Created dvPortGroup. dvPortGroup cache is :" + s_dvPortGroupCacheMap); } } else if (s_logger.isDebugEnabled()) { s_logger.debug("Detected dvPortGroup [" + dvPortGroupName + "] already present. Not attempting to create again."); } } } public void updateDvPortGroup(ManagedObjectReference dvPortGroupMor, DVPortgroupConfigSpec dvPortGroupSpec) throws Exception { synchronized (dvPortGroupMor.getValue().intern()) { ManagedObjectReference task = _context.getService().reconfigureDVPortgroupTask(dvPortGroupMor, dvPortGroupSpec); if (!_context.getVimClient().waitForTask(task)) { throw new Exception("Failed to update dvPortGroup " + dvPortGroupMor.getValue()); } } } public void updateVMWareDVSwitch(ManagedObjectReference dvSwitchMor, VMwareDVSConfigSpec dvsSpec) throws Exception { _context.getService().reconfigureDvsTask(dvSwitchMor, dvsSpec); } public TaskInfo updateVMWareDVSwitchGetTask(ManagedObjectReference dvSwitchMor, VMwareDVSConfigSpec dvsSpec) throws Exception { ManagedObjectReference task = _context.getService().reconfigureDvsTask(dvSwitchMor, dvsSpec); TaskInfo info = (TaskInfo)(_context.getVimClient().getDynamicProperty(task, "info")); _context.getVimClient().waitForTask(task); return info; } public String getDVSConfigVersion(ManagedObjectReference dvSwitchMor) throws Exception { assert (dvSwitchMor != null); DVSConfigInfo dvsConfigInfo = (DVSConfigInfo)_context.getVimClient().getDynamicProperty(dvSwitchMor, "config"); return dvsConfigInfo.getConfigVersion(); } public Map retrieveVlanPvlan(int vlanid, int secondaryvlanid, ManagedObjectReference dvSwitchMor) throws Exception { assert (dvSwitchMor != null); Map result = new HashMap(); VMwareDVSConfigInfo configinfo = (VMwareDVSConfigInfo)_context.getVimClient().getDynamicProperty(dvSwitchMor, "config"); List pvlanconfig = null; pvlanconfig = configinfo.getPvlanConfig(); if (null == pvlanconfig || 0 == pvlanconfig.size()) { return result; } // Iterate through the pvlanMapList and check if the specified vlan id and pvlan id exist. If they do, set the fields in result accordingly. for (VMwareDVSPvlanMapEntry mapEntry : pvlanconfig) { int entryVlanid = mapEntry.getPrimaryVlanId(); int entryPvlanid = mapEntry.getSecondaryVlanId(); if (entryVlanid == entryPvlanid) { // promiscuous if (vlanid == entryVlanid) { // pvlan type will always be promiscuous in this case. result.put(vlanid, HypervisorHostHelper.PvlanType.valueOf(mapEntry.getPvlanType())); } else if ((vlanid != secondaryvlanid) && secondaryvlanid == entryVlanid) { result.put(secondaryvlanid, HypervisorHostHelper.PvlanType.valueOf(mapEntry.getPvlanType())); } } else { if (vlanid == entryVlanid) { // vlan id in entry is promiscuous result.put(vlanid, HypervisorHostHelper.PvlanType.promiscuous); } else if (vlanid == entryPvlanid) { result.put(vlanid, HypervisorHostHelper.PvlanType.valueOf(mapEntry.getPvlanType())); } if ((vlanid != secondaryvlanid) && secondaryvlanid == entryVlanid) { //promiscuous result.put(secondaryvlanid, HypervisorHostHelper.PvlanType.promiscuous); } else if (secondaryvlanid == entryPvlanid) { result.put(secondaryvlanid, HypervisorHostHelper.PvlanType.valueOf(mapEntry.getPvlanType())); } } // If we already know that the vlanid is being used as a non primary vlan, it's futile to // go over the entire list. Return. if (result.containsKey(vlanid) && result.get(vlanid) != HypervisorHostHelper.PvlanType.promiscuous) return result; // If we've already found both vlanid and pvlanid, we have enough info to make a decision. Return. if (result.containsKey(vlanid) && result.containsKey(secondaryvlanid)) return result; } return result; } }