| // 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<String, List<String>> s_dvPortGroupCacheMap = null; |
| |
| public DistributedVirtualSwitchMO(VmwareContext context, ManagedObjectReference morDvs) { |
| super(context, morDvs); |
| s_dvPortGroupCacheMap = new ConcurrentHashMap<String, List<String>>(); |
| } |
| |
| public DistributedVirtualSwitchMO(VmwareContext context, String morType, String morValue) { |
| super(context, morType, morValue); |
| s_dvPortGroupCacheMap = new ConcurrentHashMap<String, List<String>>(); |
| } |
| |
| public void createDVPortGroup(DVPortgroupConfigSpec dvPortGroupSpec) throws Exception { |
| List<DVPortgroupConfigSpec> dvPortGroupSpecArray = new ArrayList<DVPortgroupConfigSpec>(); |
| dvPortGroupSpecArray.add(dvPortGroupSpec); |
| boolean dvPortGroupExists = false; |
| String dvSwitchInstance = _mor.getValue(); |
| String dvPortGroupName = dvPortGroupSpec.getName(); |
| String uniquedvPortGroupPerDvs = dvSwitchInstance + dvPortGroupName; |
| List<String> 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<String>(); |
| } |
| dvPortGroupList.add(dvPortGroupName); //does this update map? |
| } else { |
| dvPortGroupList = new ArrayList<String>(); |
| 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<Integer, HypervisorHostHelper.PvlanType> retrieveVlanPvlan(int vlanid, int secondaryvlanid, ManagedObjectReference dvSwitchMor) throws Exception { |
| assert (dvSwitchMor != null); |
| |
| Map<Integer, HypervisorHostHelper.PvlanType> result = new HashMap<Integer, HypervisorHostHelper.PvlanType>(); |
| |
| VMwareDVSConfigInfo configinfo = (VMwareDVSConfigInfo)_context.getVimClient().getDynamicProperty(dvSwitchMor, "config"); |
| List<VMwareDVSPvlanMapEntry> 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; |
| } |
| |
| } |