Package com.vmware.aurora.vc

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

/***************************************************************************
* 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.net.NoRouteToHostException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.conn.HttpHostConnectException;
import org.apache.log4j.Logger;

import com.vmware.aurora.exception.AuroraException;
import com.vmware.aurora.util.AuAssert;
import com.vmware.aurora.vc.vcservice.VcContext;
import com.vmware.aurora.vc.vcservice.VcService;
import com.vmware.vim.binding.impl.vmodl.TypeNameImpl;
import com.vmware.vim.binding.vim.Folder;
import com.vmware.vim.binding.vmodl.ManagedObject;
import com.vmware.vim.binding.vmodl.ManagedObjectReference;
import com.vmware.vim.binding.vmodl.TypeName;
import com.vmware.vim.vmomi.core.types.VmodlType;
import com.vmware.vim.vmomi.core.types.VmodlTypeMap;

/**
* A utility class to support common <code>ManagedObject</code> and
* <code>ManagedObjectReference</code> related tasks.
*/
public class MoUtil {
   private static final Logger logger = Logger.getLogger(MoUtil.class);

   private static final String MOREF_GUID_FORMAT = "%1s:%2s:%3s";

   /**
    * XXX This needs to be public only while we store moref values instead of
    * guids in the database. It should be deleted after migration to vc module.
    *
    * @param serverGuid
    * @param type
    * @param value
    * @return
    */
   public static String makeGuid(String serverGuid, String type, String value) {
      return String.format(
            MOREF_GUID_FORMAT,
            serverGuid,
            type,
            value);
   }
   /**
    * Returns a guid that represents the supplied ManagedObjectReference. Null
    * objects are represented by an empty string.
    */
   public static String morefToString(ManagedObjectReference moRef) {
      if (moRef == null) {
         return "";
      }
      return makeGuid(moRef.getServerGuid(),
            moRef.getType(),
            moRef.getValue());
   }

   /**
    * Reverse to the previous function: given a string in the format
    * MOREF_GUID_FORMAT, return ManagedObjectReference. Returns null if the
    * string has incorrect format.
    */
   public static ManagedObjectReference stringToMoref(String str) {
      if (str == null) {
         return null;
      }
      String[] comps = str.split(":");

      if (comps.length != 2 && comps.length != 3) {
         return null;
      }
      // normalize null string values
      for (int i = 0; i < comps.length; i++) {
         if (comps[i] != null &&
             (comps[i].equals("null") || comps[i].equals(""))) {
            comps[i] = null;
         }
      }
      ManagedObjectReference ref = new ManagedObjectReference();
      if (comps.length == 2) {
         ref.setServerGuid(null);
         ref.setType(comps[0]);
         ref.setValue(comps[1]);
      } else {
         ref.setServerGuid(comps[0]);
         ref.setType(comps[1]);
         ref.setValue(comps[2]);
      }
      // make sure the reference object is valid
      if (ref.getType() == null || ref.getValue() == null ||
          (ref.getServerGuid() != null &&
           !ref.getServerGuid().equals(VcContext.getServerGuid()))) {
         return null;
      }
      return ref;
   }

   /**
    * Utility method to determine if the type of a specific
    * {@link ManagedObjectReference} instance is of the provided
    * <code>clazz</code>.
    *
    * The following example demonstrates the intended usage:
    * @code {
    *    boolean isStoragePod = ManagedObjectUtil.isOfType(entity, StoragePod.class);
    * }
    *
    * This method is more type safe and less error prone compared to the
    * version which accepts string parameter:
    * {@link MoUtil#isOfType(ManagedObjectReference, String)}
    *
    * @param entity
    *    The {@link ManagedObjectReference} instance which type to be
    *    compared.
    *
    * @param clazz
    *    The <code>Class</code> instance of the class for which we want to check.
    *
    * @return
    *    <code>true</code> if the <code>entity</code> is of the specified type or
    *    <code>false</code> otherwise.
    *
    * @see #isOfType(ManagedObjectReference, String)
    */
   public static boolean isOfType(ManagedObjectReference entity, Class<?> clazz) {
      if (entity == null || clazz == null) {
         return false;
      }
      VmodlType type = VmodlTypeMap.Factory.getTypeMap().getVmodlType(clazz);
      return type.getWsdlName().equalsIgnoreCase(entity.getType());
   }

   /**
    * Utility method to determine if the type of a specific refId
    * is of the provided <code>clazz</code>.
    * @param entityId: refId of the VIM object to check.
    * @param clazz: instance of the class we want to check for.
    * @return
    *    <code>true</code> if the object referred to by the
    *    <code>entityId</code> is of the specified type or
    *    <code>false</code> otherwise.
    */
   public static boolean isOfType(String entityId, Class<?> clazz) {
      return isOfType(stringToMoref(entityId), clazz);
   }

   /**
    * Convert a managed object reference to managed object.
    */
   public static <T extends ManagedObject> T
   getManagedObject(ManagedObjectReference moRef) {
      AuAssert.check(moRef != null &&
             moRef.getValue() != null &&
             (moRef.getServerGuid() == null ||
              moRef.getServerGuid().equals(VcContext.getServerGuid())));
      // Sun's javac requires explicit casting.
      // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954
      AuAssert.check(VcContext.isInSession());
      return VcContext.getService().<T>getManagedObject(moRef);
   }

   /**
    * Convert a list of managed object reference to managed object list.
    */
   public static <T extends ManagedObject> List<T>
   getManagedObjects(ManagedObjectReference[] moRefs) throws Exception {
      ArrayList<T> list = new ArrayList<T>(moRefs.length);
      for (ManagedObjectReference moRef : moRefs) {
         list.add(MoUtil.<T>getManagedObject(moRef));
      }
      return list;
   }

   public static Folder getRootFolder() throws Exception {
      AuAssert.check(VcContext.isInSession());
      VcService svc = VcContext.getService();
      ManagedObjectReference rootFolderRef =
         svc.getServiceInstanceContent().getRootFolder();
      return svc.getManagedObject(rootFolderRef);
   }

   /**
    * Helper function to get all child entities of type <code>T</code>
    * in the <code>Folder</code> managed object.
    */
   public static <T extends ManagedObject> List<T>
   getChildEntity(Folder folder, Class<T> clazz)
   {
      AuAssert.check(VcContext.isInSession());
      VcService svc = VcContext.getService();
      ManagedObjectReference[] childEntities = folder.getChildEntity();
      List<T> entities = new ArrayList<T>();
      for (ManagedObjectReference child : childEntities) {
         if (isOfType(child, clazz)) {
            entities.add(svc.<T>getManagedObject(child));
         }
      }
      return entities;
   }

   /**
    * Similar to <code>getChildEntity()</code>, but does a deep traversal to
    * find all descendants of type <code>T</code> starting with a given folder.
    * @param <T>
    * @param folder
    * @param clazz
    * @return
    */
   public static <T extends ManagedObject> List<ManagedObjectReference>
   getDescendantsMoRef(Folder folder, Class<T> clazz) {
      List<ManagedObjectReference> descendants =
         new ArrayList<ManagedObjectReference>();
      getDescendants(folder, clazz, descendants);
      return descendants;
   }

   private static <T extends ManagedObject> void
   getDescendants(Folder folder, Class<T> clazz,
                  List<ManagedObjectReference> descendants)
   {
      AuAssert.check(VcContext.isInSession());
      VcService svc = VcContext.getService();
      ManagedObjectReference[] childEntities = folder.getChildEntity();
      for (ManagedObjectReference child : childEntities) {
         if (isOfType(child, clazz)) {
            descendants.add(child);
         } else if(isOfType(child, Folder.class)) {
            Folder childFolder = svc.<Folder>getManagedObject(child);
            getDescendants(childFolder, clazz, descendants);
         }
      }
   }

   /**
    * Traverse the managed entity tree to find an ancestor of type <T>.
    * @param <T>
    * @param parent
    * @param clazz
    * @return
    */
   protected static <T extends ManagedObject> ManagedObjectReference
   getAncestorMoRef(ManagedObjectReference parent, Class<T> clazz) {
      AuAssert.check(VcContext.isInSession());
      VcService svc = VcContext.getService();
      if (isOfType(parent, clazz)) {
         return parent;
      } else {
         ManagedObject obj = svc.getManagedObject(parent);
         if (obj instanceof Folder) {
            Folder folder = (Folder)obj;
            return getAncestorMoRef(folder.getParent(), clazz);
         }
      }
      logger.error("cannot find ancestor VC object of type " +
                   clazz.getName() + " for " + parent);
      throw AuroraException.INTERNAL();
   }

   /**
    * Returns TypeName for the passed moRef.
    * @param moRef
    * @return TypeName
    */
   public static TypeName getTypeName(ManagedObjectReference moRef) {
      return new TypeNameImpl(moRef.getType());
   }

   /**
    * Returns true when an exception is caused by connection or network
    * issues. This includes the connection problems due to vc being down.
    * @param e  exception to check
    * @return true for network related vc exceptions
    */
   public static boolean isNetworkException(Throwable e) {
      return e instanceof HttpHostConnectException || /* Temporary connectivity loss?      */
             e instanceof NoRouteToHostException   || /* Network glitch.                   */
             e instanceof SocketTimeoutException   || /* Client side. Session might be ok. */
             e instanceof SocketException;            /* Many cases including vc shutdown. */
   }

   /**
    * VLSI doesn't convert some special characters supported by VC
    * from URL format to String format on the receive path. See PR 737040.
    *
    * @param s
    * @return
    */
   public static String fromURLString(String s) {
      if (s == null) {
         return s;
      }
      StringBuffer buf = new StringBuffer();
      int i = 0;
      while (i < s.length()) {
         if (s.startsWith("%", i)) {
            // scan the next two characters
            String code = s.substring(i + 1, i + 3);
            if (code.equals("25")) {
               buf.append('%');
               i += 3;
               continue;
            }
            if (code.equals("2f") || code.equals("2F")){
               buf.append('/');
               i += 3;
               continue;
            }
            if (code.equals("5c") || code.equals("5C")){
               buf.append('\\');
               i += 3;
               continue;
            }
         }
         buf.append(s.charAt(i));
         i++;
      }
      return buf.toString();
   }

   public static String toURLString(String s) {
      if (s == null) {
         return s;
      }
      StringBuffer buf = new StringBuffer();
      for (int i = 0; i < s.length(); i++) {
         char ch = s.charAt(i);
         switch (ch) {
         case '%':
            buf.append("%25");
            break;
         case '/':
            buf.append("%2f");
            break;
         case '\\':
            buf.append("%5c");
            break;
         default:
            buf.append(ch);
         }
      }
      return buf.toString();
   }
}
TOP

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

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.