Package com.vmware.aurora.vc

Source Code of com.vmware.aurora.vc.VcResourcePoolImpl

/***************************************************************************
* Copyright (c) 2012-2013 VMware, Inc. All Rights Reserved.
* 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 com.vmware.aurora.vc;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import com.vmware.aurora.util.AuAssert;
import com.vmware.aurora.vc.VcTask.TaskType;
import com.vmware.aurora.vc.VcTaskMgr.IVcPseudoTaskBody;
import com.vmware.aurora.vc.VcTaskMgr.IVcTaskBody;
import com.vmware.aurora.vc.vcevent.VcEventHandlers.VcEventType;
import com.vmware.aurora.vc.vcservice.VcContext;
import com.vmware.aurora.vc.vcservice.VcSession;
import com.vmware.vim.binding.impl.vim.ResourceConfigSpecImpl;
import com.vmware.vim.binding.vim.ClusterComputeResource;
import com.vmware.vim.binding.vim.Folder;
import com.vmware.vim.binding.vim.HttpNfcLease;
import com.vmware.vim.binding.vim.ImportSpec;
import com.vmware.vim.binding.vim.ManagedEntity;
import com.vmware.vim.binding.vim.ResourceAllocationInfo;
import com.vmware.vim.binding.vim.ResourceConfigSpec;
import com.vmware.vim.binding.vim.ResourcePool;
import com.vmware.vim.binding.vim.ResourcePool.ResourceUsage;
import com.vmware.vim.binding.vim.VirtualApp;
import com.vmware.vim.binding.vim.event.ResourcePoolCreatedEvent;
import com.vmware.vim.binding.vim.event.ResourcePoolEvent;
import com.vmware.vim.binding.vim.fault.DuplicateName;
import com.vmware.vim.binding.vim.vApp.ProductInfo;
import com.vmware.vim.binding.vim.vApp.VAppConfigSpec;
import com.vmware.vim.binding.vim.vm.ConfigSpec;
import com.vmware.vim.binding.vim.vm.FileInfo;
import com.vmware.vim.binding.vmodl.ManagedObject;
import com.vmware.vim.binding.vmodl.ManagedObjectReference;
import com.vmware.vim.binding.vmodl.fault.ManagedObjectNotFound;

public interface VcResourcePool extends VcObject {

   /**
    * @return the full path name
    */
   abstract String getPath();

   abstract boolean isVApp();

   abstract String getVersion();

   abstract String getFullVersion();

   /**
    * Returns the closest ancestor vApp of the current RP or null if
    * this RP is not under any vApps.
    * @return ancestor vApp RP.
    */
   abstract VcResourcePool getAncestorVAppRp();

   abstract boolean isHADRSCompatible();

   abstract boolean isLeaf();

   abstract boolean isRootRP();

   /**
    * @return reasons for the VC resource pool to be incompatible for resource bundle
    */
   abstract List<String> getIncompatReasonsForRBQual();

   /**
    * @return true if the VC resource pool can be used in a resource bundle.
    */
   abstract boolean isQualifiedResourceBundleRP();

   /**
    * @return the VC cluster that contains this resource pool
    */
   abstract VcCluster getVcCluster();

   /**
    * @return the parent VC resource pool, null if the current is root.
    */
   abstract VcResourcePool getParent();

   /**
    * Create a child resource pool
    * @param name child resource pool name
    * @param cpuAllocation
    * @param memAllocation
    * @return the new resource pool
    * @throws Exception
    */
   abstract VcResourcePool createChild(final String name,
         final ResourceAllocationInfo cpuAllocation,
         final ResourceAllocationInfo memAllocation) throws Exception;

   /**
    * Create a child resource pool
    * @param name child resource pool name
    * @param cpuAllocation
    * @param memAllocation
    * @param force true to suppress DuplicateName exception, and remove existing child RP
    *              false to throw DuplicateName exception.
    * @return the new resource pool
    * @throws Exception
    */
   abstract VcResourcePool createChild(final String name,
         final ResourceAllocationInfo cpuAllocation,
         final ResourceAllocationInfo memAllocation,
         final boolean force) throws Exception;
   /**
    * @return child resource pools
    */
   abstract List<VcResourcePool> getChildren();

   /**
    * @return VMs under the resource pool
    */
   abstract List<VcVirtualMachine> getChildVMs();

   /**
    * Import a VM template (step 1).
    * @param spec VM template import spec
    * @return lease used for uploading OVF files
    * @throws Exception
    * XXX do we really need to copy files from CMS to datastores?
    * TODO: not tested
    */
   abstract HttpNfcLease importVApp(ImportSpec spec) throws Exception;

   /**
    * Create a VM under the resource pool
    * @param config VM configuration
    * @param callback (optional) call-back function for the task
    * @return task for the VM creation operation
    * @throws Exception
    * TODO: not tested
    */
   abstract VcTask createVm(final ConfigSpec config,
         final IVcTaskCallback callback, Folder folder) throws Exception;

   abstract VcVirtualMachine createVm(ConfigSpec config, Folder folder) throws Exception;

   /**
    * Use this method when the VM needs to be created on a specific datastore
    * and when it is not already captured in the input <code>config</code>.
    * @throws Exception
    */
   abstract VcVirtualMachine createVm(ConfigSpec config, VcDatastore ds)
         throws Exception;
  
   /**
    * Use this method when the VM needs to be created on a specific datastore
    * and in a specific vm folder
    * @throws Exception
    */
   abstract VcVirtualMachine createVm(ConfigSpec config, VcDatastore ds, Folder folder)
         throws Exception;

   /**
    * Finds a VM by its name and deletes it.
    *
    * @throws Exception
    */
   abstract void destroyVm(String vmName) throws Exception;

   /**
    * Remove all child resource pools recursively.
    * @throws Exception
    */
   abstract void destroyChildren() throws Exception;

   /**
    * Remove this resource pool.
    * @throws Exception
    */
   abstract void destroy() throws Exception;

   /**
    * Reconfigure resource settings.
    * @name optional, to rename resource pool
    * @cpuAllocation optional, change CPU allocation
    * @memAllocation optional, change memory allocation
    * @throws Exception
    */
   abstract void updateConfig(final String name,
         final ResourceAllocationInfo cpuAllocation,
         final ResourceAllocationInfo memAllocation) throws Exception;

   /**
    * Reconfigure version and fullVersion for vApp
    * @version
    * @fullVersion
    * @throws Exception
    *
    */
   abstract void updateVAppConfig(VAppConfigSpec spec) throws Exception;

   abstract ResourceAllocationInfo getCpuAllocationInfo();

   abstract ResourceAllocationInfo getMemAllocationInfo();

   abstract ResourceUsage getCpuUsageInfo();

   abstract ResourceUsage getMemUsageInfo();

   abstract String getName();

}

@SuppressWarnings("serial")
class VcResourcePoolImpl extends VcObjectImpl implements VcResourcePool {
   private String path;  // full path of the resource pool from the cluster
   private String name;  // name of the resource pool

   private ManagedObjectReference owner; // the cluster that contains the resource pool
   private List<ManagedObjectReference> childVMs;
   private ManagedObjectReference parent;
   private boolean isVApp;
   private String version;
   private String fullVersion;
   private ResourceAllocationInfo cpuAlloc;
   private ResourceAllocationInfo memAlloc;

   // Usage fields
   private ResourceUsage cpuUsage;
   private ResourceUsage memUsage;

   /**
    * Sync request to send update requests for a subtree of RPs.
    */
   protected static class SyncRequest extends VcInventory.SyncRequest {
      SyncRequest(ManagedObjectReference moRef, VcInventory.SyncRequest parent) {
         super(moRef, parent);
      }

      @Override
      protected void syncChildObjects(VcObject obj) {
         if (obj instanceof VcResourcePoolImpl) {
            VcResourcePoolImpl rp = (VcResourcePoolImpl)obj;
            for (ManagedObjectReference child : rp.getChildRps()) {
               add(new SyncRequest(child, this));
            }
         }
      }
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getPath()
    */
   @Override
   public String getPath() { return path; }

   @Override
   protected void update(ManagedObject mo) throws Exception {
      ResourcePool rp = (ResourcePool)mo;
      childVMs = Arrays.asList(rp.getVm());
      owner = rp.getOwner();
      parent = rp.getParent();
      name = rp.getName();
      isVApp = (rp instanceof VirtualApp);
      if (isVApp) {
         VirtualApp vapp = (VirtualApp)mo;
         ProductInfo[] pInfo = vapp.getVAppConfig().getProduct();
         version = pInfo[0].getVersion();
         fullVersion = pInfo[0].getFullVersion();
      }
      ResourceConfigSpec config = rp.getConfig();
      cpuAlloc = config.getCpuAllocation();
      memAlloc = config.getMemoryAllocation();

      // XXX: The cpuUsgae and memUsgae should really belong
      // to the runtime info. We putting them into configuration category is
      // to temporarily fix bug 865341 in Borealis. Should be refactorred later.
      ResourcePool.RuntimeInfo runtime = rp.getRuntime();
      cpuUsage = runtime.getCpu();
      memUsage = runtime.getMemory();

      for (ManagedObjectReference vmRef : childVMs) {
         VcCache.putVmRpPair(vmRef, getMoRef());
      }
      updatePath();
   }

   @Override
   protected void updateRuntime(ManagedObject mo) throws Exception {
      ResourcePool rp = (ResourcePool)mo;
      ResourcePool.RuntimeInfo runtime = rp.getRuntime();
      cpuUsage = runtime.getCpu();
      memUsage = runtime.getMemory();
   }

   protected VcResourcePoolImpl(ResourcePool rp) throws Exception {
      super(rp);
      update(rp);
      updateRuntime(rp);
   }

   /**
    * Slow way to load an RP, because we need to construct the RP paths
    * from the VC RP tree and we cannot use VC cache to lookup parents.
    * @param rp
    * @return path to RP
    * @throws Exception
    */
   private static String calculatePathSlow(ResourcePool rp) throws Exception {
      LinkedList<ResourcePool> rpStack  = new LinkedList<ResourcePool>();
      while (rp != null) {
         ManagedEntity parent = MoUtil.getManagedObject(rp.getParent());
         AuAssert.check(parent != null);
         if (!(parent instanceof ResourcePool)) {
            // skip the root RP's name in the path
            break;
         }
         rpStack.addFirst(rp);
         rp = (ResourcePool)parent;
      }
      // Path is encoded as: [cluster]/path/to/rpName
      StringBuffer pathBuf = new StringBuffer();
      ClusterComputeResource cluster = MoUtil.getManagedObject(rp.getOwner());
      pathBuf.append('[').append(MoUtil.fromURLString(cluster.getName())).append(']');
      for (ResourcePool r : rpStack) {
         pathBuf.append("/").append(MoUtil.fromURLString(r.getName()));
      }
      return pathBuf.toString();
   }

   /*
    * Calculate and update the path in the resource tree.
    *
    * Note: Cannot use VcCache.get() because this function is called by a
    *       CmsWorker thread.
    */
   private void updatePath() throws Exception {
      if (isRootRP()) {
         VcCluster cluster = VcCache.lookup(owner);
         if (cluster != null) {
            path = '[' + cluster.getName() + ']';
            return;
         }
      } else {
         VcResourcePool parentRP = VcCache.lookup(parent);
         if (parentRP != null) {
            path = parentRP.getPath() + "/" + getName();
            return;
         }
      }
      path = calculatePathSlow((ResourcePool)getManagedObject());
      return;
   }

   @Override
   public String toString() {
      Long cpuLimit = cpuAlloc.getLimit();
      Long cpuReservation = cpuAlloc.getReservation();
      Long memLimit = memAlloc.getLimit();
      Long memReservation = memAlloc.getReservation();
      return String.format("RP[%s](cpu:R=%d,L=%d,mem:R=%d,L=%d,#vm=%d)", path,
            cpuReservation, cpuLimit, memReservation, memLimit, childVMs.size());
   }

   private List<ManagedObjectReference> getChildRps() {
      ResourcePool rp = null;
      if (VcContext.isInSession()) {
         rp = getManagedObject();
      } else {
         rp = VcContext.inVcSessionDo(new VcSession<ResourcePool>() {
            @Override
            protected ResourcePool body() throws Exception {
               return getManagedObject();
            }
         });
      }
      return Arrays.asList(rp.getResourcePool());
   }

   @Override
   public boolean isLeaf() {
      return getChildRps().isEmpty();
   }

   @Override
   public boolean isVApp() {
      return isVApp;
   }

   @Override
   public String getVersion() {
      return version;
   }

   @Override
   public String getFullVersion() {
      return fullVersion;
   }

   @Override
   public VcResourcePool getAncestorVAppRp() {
      VcResourcePool parentRp = this;
      while ((parentRp = parentRp.getParent()) != null) {
         if (parentRp.isVApp()) {
            return parentRp;
         }
      }
      return null;
   }

   /**
    * Helper class to define a walker routine for traversing a ResourcePool tree.
    */
   abstract static class RPWalker<T> {
      /*
       * The list that holds objects to be returned.
       */
      public List<T> results;
      public RPWalker() {
         results = new ArrayList<T>();
      }
      /**
       * @return true if needs to traverse child nodes
       */
      abstract public boolean processRP(VcResourcePool rp) ;
   }

   /**
    * Walk the resource pool in pre-order.
    *
    * @param <T> Class of data created by walker
    * @param rp Root resource pool
    * @param walker Tree traversing code
    * @return the collection of data created by walker
    * @throws Exception
    */
   private static <T> List<T>
   walkResourcePools(VcResourcePool rp, RPWalker<T> walker)
   {
      if (walker.processRP(rp)) {
         for (VcResourcePool child : rp.getChildren()) {
            walkResourcePools(child, walker);
         }
      }
      return walker.results;
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#isHADRSCompatible()
    */
   @Override
   public boolean isHADRSCompatible() {
      return getVcCluster().getHADRSIncompatReasonsForAlert().isEmpty();
   }

   @Override
   public List<String> getIncompatReasonsForRBQual() {
      List<String> reasons = VcUtil.getCPUMemAllocIncompatReasons(cpuAlloc, memAlloc);
      reasons.addAll(getVcCluster().getHADRSIncompatReasonsForRBQual());
      return reasons;
   }

   @Override
   public boolean isQualifiedResourceBundleRP() {
      return getIncompatReasonsForRBQual().isEmpty();
   }

   private List<VcResourcePool>
   getQualifiedRPsWork(final boolean forBundle) {
      return walkResourcePools(this, new RPWalker<VcResourcePool>() {
         public boolean processRP(VcResourcePool rp) {
            if (rp.isVApp()) {
               // If RP is a vapp, skip the subtree.
               logger.debug("Skip VirtualApp RP " + rp.getName());
               return false;
            } if (!rp.isLeaf()) {
               // Not a leaf not, visit the child RPs.
               return true;
            } else {
               if (!forBundle || rp.isQualifiedResourceBundleRP()) {
                  results.add(rp);
               }
               return false;
            }
         }
      });
   }

   /**
    * Get RPs in the subtree qualified for resource bundle.
    */
   protected List<VcResourcePool> getQualifiedRPs() {
      return getQualifiedRPsWork(true);
   }

   /**
    * Get all leaf RPs in the subtree.
    */
   protected List<VcResourcePool> getAllRPs() {
      return getQualifiedRPsWork(false);
   }

   /**
    * Search for a resource pool that matches the path.
    * The path should be in the form: "[clusterName]/rp1/rp2".
    * @param path
    * @return the matching resource pool, null if not found
    * @throws Exception
    */
   protected VcResourcePool searchRP(final String path) {
      List<VcResourcePool> result =
         walkResourcePools(this, new RPWalker<VcResourcePool>() {
            public boolean processRP(VcResourcePool rp) {
               if (rp.getPath().equals(path)) {
                  results.add(rp);
                  return false;
               }
               if (path.startsWith(rp.getPath())) {
                  return true;
               }
               return false;
            }
         });
      if (result.isEmpty()) {
         return null;
      }
      return result.get(0);
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getVcCluster()
    */
   @Override
   public VcCluster getVcCluster() {
      return VcCache.get(owner);
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getParent()
    */
   @Override
   public VcResourcePool getParent() {
      AuAssert.check(VcContext.isInSession());
      if (isRootRP()) {
         return null;
      }
      return VcCache.get(parent);
   }

   public VcResourcePool createChild(final String name,
         final ResourceAllocationInfo cpuAllocation,
         final ResourceAllocationInfo memAllocation) throws Exception {
      return createChild(name, cpuAllocation, memAllocation, false);
   }
   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#createChild(java.lang.String, com.vmware.vim.binding.vim.ResourceAllocationInfo, com.vmware.vim.binding.vim.ResourceAllocationInfo)
    */
   @Override
   public VcResourcePool createChild(final String name,
         final ResourceAllocationInfo cpuAllocation,
         final ResourceAllocationInfo memAllocation,
         final boolean force) throws Exception
   {
      final ResourceConfigSpec spec = new ResourceConfigSpecImpl(
               null, null, null, cpuAllocation, memAllocation);
      ManagedObjectReference ref =
         VcContext.getTaskMgr().execPseudoTask("ResourcePool.createResourcePool",
            VcEventType.ResourcePoolCreated, getMoRef(),
            new IVcPseudoTaskBody() {
         @Override
         public final ManagedObjectReference body() throws Exception {
            final ResourcePool rp = getManagedObject();
            ManagedObjectReference child = null;
            //at least execute once
            while (true) {
               try {
                  child = rp.createResourcePool(name, spec);
                  break;
               } catch (DuplicateName ex) {
                  if (force) {
                     //suppress this exception, and remove duplicated RP, then retry.
                     update();
                     for (VcResourcePool vcChildRP : getChildren()) {
                        String childName = vcChildRP.getName();
                        if (childName.equals(name)) {
                           vcChildRP.destroy();
                           break;
                        }
                     }
                  } else {
                     throw ex;
                  }
               }
            }
            return child;
         }
      });

      try {
         return VcCache.get(ref);
      } catch (Exception e) {
         // XXX fix exception here
         logger.error(this + ":race detected in creating RP " + name, e);
         throw new Exception("bad moref");
      }
   }

   /**
    * Returns "target moRef" for an RP event. For createResourcePool operation,
    * we use parent moRef as the key (child moRef not available at start) and the
    * target for the corresponding event is RP parent. In all other cases, target
    * moRef is RP itself.
    * @param event
    * @return target moRef
    */
   protected static ManagedObjectReference getEventTargetMoRef(ResourcePoolEvent event) {
      if (event instanceof ResourcePoolCreatedEvent) {
         ResourcePoolCreatedEvent rpCreatedEvent = (ResourcePoolCreatedEvent) event;
         if (rpCreatedEvent != null) {
            return rpCreatedEvent.getParent().getResourcePool();
         }
      } else if (event.getResourcePool() != null) {
         return event.getResourcePool().getResourcePool();
      }
      return null;
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getChildren()
    *
    * This function is used to explore RPs in the wild while they
    * are being concurrently created/deleted to find candidates for
    * RBs. Skip over stale/deleted RPs.
    */
   @Override
   public List<VcResourcePool> getChildren() {
      return VcCache.getPartialList(getChildRps(), getMoRef());
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getChildVMs()
    */
   @Override
   public List<VcVirtualMachine> getChildVMs() {
      return VcCache.getPartialList(childVMs, getMoRef());
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#importVApp(com.vmware.vim.binding.vim.ImportSpec)
    */
   @Override
   public HttpNfcLease importVApp(ImportSpec spec) throws Exception {
      AuAssert.check(VcContext.isInTaskSession());
      ResourcePool rp = getManagedObject();
      VcDatacenter dc = getVcCluster().getDatacenter();
      return MoUtil.getManagedObject(rp.importVApp(spec, dc.getVmFolderMoRef(), null));
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#createVm(com.vmware.vim.binding.vim.vm.ConfigSpec, com.vmware.aurora.vc.IVcTaskCallback)
    */
   @Override
   public VcTask createVm(final ConfigSpec config, final IVcTaskCallback callback, final Folder folder)
   throws Exception {
      final VcDatacenter dc = getVcCluster().getDatacenter();
      VcTask task = VcContext.getTaskMgr().execute(new IVcTaskBody() {
         public VcTask body() throws Exception {
            Folder vmFolder = folder;
            if (vmFolder == null)
               vmFolder = dc.getVmFolder();
            return new VcTask(TaskType.CreateVm,
                  vmFolder.createVm(config, moRef, null), callback);
         }
      });
      logger.debug("create_vm task " + "VM " + config.getName() +
            " under " + this + " created");
      return task;
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#createVm(com.vmware.vim.binding.vim.vm.ConfigSpec)
    */
   @Override
   public VcVirtualMachine createVm(ConfigSpec config, Folder vmFolder) throws Exception {
      VcTask task = createVm(config, VcCache.getRefreshVcTaskCB(this), vmFolder);
      VcVirtualMachine vm = (VcVirtualMachine) task.waitForCompletion();
      return vm;
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#createVm(com.vmware.vim.binding.vim.vm.ConfigSpec, com.vmware.aurora.vc.VcDatastore)
    */
   @Override
   public VcVirtualMachine createVm(ConfigSpec config, VcDatastore ds)
         throws Exception {
      return createVm(config, ds, null);
   }
  
   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#createVm(com.vmware.vim.binding.vim.vm.ConfigSpec, com.vmware.aurora.vc.VcDatastore, com.vmware.vim.binding.vim.Folder)
    */
   @Override
   public VcVirtualMachine createVm(ConfigSpec config, VcDatastore ds, Folder vmFolder)
         throws Exception {
      String vmPathName = String.format("[%s]", ds.getURLName());
      FileInfo info = new com.vmware.vim.binding.impl.vim.vm.FileInfoImpl();
      info.setVmPathName(vmPathName);
      AuAssert.check(config.getFiles() == null);
      config.setFiles(info);
      return createVm(config, vmFolder);
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#destroyVm(java.lang.String)
    */
   @Override
   public void destroyVm(String vmName) throws Exception {
      for (ManagedObjectReference vm : childVMs) {
         VcVirtualMachine vcVm = VcCache.getIgnoreMissing(vm);
         if (vcVm != null) {
            String vcVmName = vcVm.getName();
            if (vcVmName != null && vmName.equals(vcVmName)) {
               vcVm.destroy();
               return;
            }
         }
      }
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#destroyChildren()
    */
   @Override
   public void destroyChildren() throws Exception {
      AuAssert.check(VcContext.isInTaskSession());
      ResourcePool rp = getManagedObject();
      rp.destroyChildren();
      for (ManagedObjectReference rpRef : getChildRps()) {
         VcCache.purge(rpRef);
      }
      update();
   }

   /**
    * Remove this resource pool.
    * @param callback (optional) task callback
    * @throws Exception
    */
   private VcTask destroy(final IVcTaskCallback callback) throws Exception {
      VcTask task = VcContext.getTaskMgr().execute(new IVcTaskBody() {
         public VcTask body() throws Exception {
            final ResourcePool rp = getManagedObject();
            return new VcTask(TaskType.DestroyRp, rp.destroy(), callback);
         }
      });

      logger.debug("destroy_rp task RP " + this + " created");
      return task;
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#destroy()
    */
   @Override
   public void destroy() throws Exception {
      final ManagedObjectReference oldParent = parent;
      try {
         VcTask task = destroy(new IVcTaskCallback() {
            @Override
            public void completeCB(VcTask task) {
               VcCache.purge(getMoRef());
               VcCache.refresh(oldParent);
            }
            @Override
            public void syncCB() {
               VcCache.sync(oldParent);
            }});
         task.waitForCompletion();
      } catch (ManagedObjectNotFound e) {
         logger.info("cannot destroy " + this + ", not found.");
      }
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#updateConfig(java.lang.String, com.vmware.vim.binding.vim.ResourceAllocationInfo, com.vmware.vim.binding.vim.ResourceAllocationInfo)
    */
   @Override
   public void updateConfig(final String name,
         final ResourceAllocationInfo cpuAllocation,
         final ResourceAllocationInfo memAllocation) throws Exception {
      VcContext.getTaskMgr().execPseudoTask("ResourcePool.updateConfig",
            VcEventType.ResourcePoolReconfigured, getMoRef(),
            new IVcPseudoTaskBody() {
         @Override
         public ManagedObjectReference body() throws Exception {
            final ResourcePool rp = getManagedObject();
            ResourceConfigSpec spec = null;
            if (cpuAllocation != null || memAllocation != null) {
               spec = new ResourceConfigSpecImpl(
                     null, null, null, cpuAllocation, memAllocation);
               }
            rp.updateConfig(MoUtil.toURLString(name), spec);
            update();
            VcCache.refresh(parent)// to refresh its parent's cpu/mem usage
            return getMoRef();
         }
      });
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#updateConfig(java.lang.String, com.vmware.vim.binding.vim.ResourceAllocationInfo, com.vmware.vim.binding.vim.ResourceAllocationInfo)
    */
   @Override
   public void updateVAppConfig(final VAppConfigSpec spec) throws Exception {
      // We're not using pseudotask but invoking one time synchronously as this is a short call
      // and updateVAppConfig also does not generate a specific event. This is also a one-time
      // call if the version does not match the CMS version, which will happen after vum update.
      final VirtualApp vapp = (VirtualApp)getManagedObject();
      vapp.updateVAppConfig(spec);
      update();
   }


   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getCpuAllocationInfo()
    */
   @Override
   public ResourceAllocationInfo getCpuAllocationInfo() {
      return cpuAlloc;
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getMemAllocationInfo()
    */
   @Override
   public ResourceAllocationInfo getMemAllocationInfo() {
      return memAlloc;
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getCpuUsageInfo()
    */
   @Override
   public ResourceUsage getCpuUsageInfo() {
      return cpuUsage;
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getMemUsageInfo()
    */
   @Override
   public ResourceUsage getMemUsageInfo() {
      return memUsage;
   }

   @Override
   public boolean isRootRP() {
      return !(MoUtil.isOfType(parent, ResourcePool.class) ||
               MoUtil.isOfType(parent, VirtualApp.class));
   }

   /* (non-Javadoc)
    * @see com.vmware.aurora.vc.VcResourcePool#getName()
    */
   @Override
   public String getName() {
      return isRootRP() ? getPath() :
             MoUtil.fromURLString(name);
   }
}
TOP

Related Classes of com.vmware.aurora.vc.VcResourcePoolImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.