使用VMware VSphere WebService SDK进行开发 (一)——基本信息阐述

网上对于VSphere WebService SDK的介绍比较少(至少我能查到的资料比较少),官方提供的也是英文版的api,而且没有注明使用方法。最近接触到关于VSphere WebService SDK的开发,刚开始也是烦躁,比如要获取一个cpu使用情况的信息,按照惯例,API应该提供类似:long
getCpuUsage() 之类的接口,但是绝逼没有那么easy,不过很快掌握了规律。我觉得有必要分享一下我所了解到的知识点,希望能够给各位读者有那么一点抛砖引玉的作用。

我准备通过几篇文章来主要讲述如何使用VSphere WebService SDK 进行对资源信息的监控和告警的采集。对资源监视的监控主要包括:对虚拟机(Virtual Machine)信息的监控(cpu使用情况、磁盘的写入以及读取速度、内存的滞后时间、网络的丢弃的传输和接收的数据报数等待)、对主机(HostSystem)的监控、对集群(Cluster,
Compute Resource)信息的监控. 告警也是对这几个主要的对象进行告警采集。

关于软件的安装,譬如vSphere的配置以及vSphere Client的安装就此略过。我这里使用的版本是VMware-vSphere-SDK-5.0.0-429209。

本篇文章主要先阐述一些基本知识。

VMware vSphere支持健壮的、容错的虚拟化应用、网络和存储。vSphere提供许多可选的组件和模块,例如VMware High Availability(HA) 和VMware VMotion。VMware vSphere
Web Services SDK提供给Web Services开发者通过编程的方式访问vSphere组件。

vSphere API以无关语言的Web Serivce的形式实现,客户端应用通过远程调用来访问ESX/ESXi, VCenter vSphere systems上的服务和组件。

VMware vSphere客户端程序基于一个异步通讯的分布式架构模型,架构的基础基于server-side managed object, client-side managed object references和data
objects.

Managed Object: 在vSphere server(ESX/ESXi 或 vCenter Server system)上,代表着vSphere的服务和组件。服务包括 PropertyCollector,
SearchIndex, PerformanceManager和ViewManager。组件包括inventory objects例如VirtualMachine,Datastore和Folder.

Managed Object refereneces:是客户端应用服务器端managed objects.你的客户端应用程序通过使用ManagedObjectReference objects来向服务器发送请求操作。在object的生命周期内ManagedObjectReferences是唯一和持久有效地。当一个存在与清单中由于过期sessions或服务器重启而删除的object的应用会依然存在。假如你删除一个object,例如一个虚拟机,然后又找回它,对它的引用将改变。

Data objects:包含着关于managed objects的信息,你的客户端程序发送data objects和接收data objects与一个vSphere server, 不同的标准和功能object例如VirtualMachineConfigSp和HostCapability.

下图清楚的说明了这三种数据对象及
vSphere Sever 与 client 的关系。

在这三种数据对象中,MO 代表了服务器端的服务或组件,他们都直接或间接继承自 ManagedEntity 抽象类。下面的类图展示了目前
vSphere Infrastructure 中的 7 种最重要的 MO 类型和它们的继承关系,它们代表了 vSphere Infrastructure 中的 7 种组件或者实体。

使用
SDK 开发自己的 vSphere 客户端程序,首要的问题就是如何访问和遍历在 vSphere Inventory 中的对象。下面我们将介绍这方面的内容。

vSphere Inventory 介绍

vSphere inventory 其实就是 vSphere datacenter 及其管理的对象。在 vSphere inventory 中包含了以下三种类型的对象:

在 datacenter 中被管理的系统,比如 Host、VirtualMachine、VirtualApp 等。

具有一定功能的组件,比如 ComputeResource、DataStore,、Network 等。

负责组织归类的组件,它们负责把 datacenter 中的对象按照层级关系组织起来形成了一个树状结构,比如 Folder 和 DataCenter。

ESX/ESXi server 和 vCenter 的 inventory 结构是类似的,只是在 ESX server
中,有些对象的数量有限制,比如在一个 ESX server 的 inventory 中只能有一个 Host 实体。下面两张图分别给出了 vCenter 这 ESX server 的 inventory 的结构。

vCenter Inventory 结构

上面这个关系图很关键,对于系统中关键信息的检索,首先要根据这张图搜寻相关的ManagedObjectReference对象,然后根据此对象的属性树进行遍历。比如搜寻DataCenter对象的相关信息:

	private static TraversalSpec getDatacenterTraversalSpec()
	{
		SelectionSpec sSpec = new SelectionSpec();
		sSpec.setName("VisitFolders");

		TraversalSpec traversalSpec = new TraversalSpec();
		traversalSpec.setName("VisitFolders");
		traversalSpec.setType("Folder");
		traversalSpec.setPath("childEntity");
		traversalSpec.setSkip(false);
		traversalSpec.getSelectSet().add(sSpec);
		return traversalSpec;
	}

	private static ManagedObjectReference getDatacenterByName(String datacenterName)
	{
		ManagedObjectReference retVal = null;
		ManagedObjectReference rootFolder = serviceContent.getRootFolder();
		try
		{
			TraversalSpec tSpec = getDatacenterTraversalSpec();
			PropertySpec propertySpec = new PropertySpec();
			propertySpec.setAll(Boolean.FALSE);
			propertySpec.getPathSet().add("name");
			propertySpec.setType("Datacenter");

			ObjectSpec objectSpec = new ObjectSpec();
			objectSpec.setObj(rootFolder);
			objectSpec.setSkip(Boolean.TRUE);
			objectSpec.getSelectSet().add(tSpec);

			PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec();
			propertyFilterSpec.getPropSet().add(propertySpec);
			propertyFilterSpec.getObjectSet().add(objectSpec);

			List<PropertyFilterSpec> listfps = new ArrayList<PropertyFilterSpec>(1);
			listfps.add(propertyFilterSpec);
			List<ObjectContent> listobcont = retrievePropertiesAllObjects(listfps);

			if (listobcont != null)
			{
				for (ObjectContent oc : listobcont)
				{
					ManagedObjectReference mr = oc.getObj();
					String dcnm = null;
					List<DynamicProperty> dps = oc.getPropSet();
					if (dps != null)
					{
						for (DynamicProperty dp : dps)
						{
							dcnm = (String) dp.getVal();
						}
					}

					if (dcnm != null && dcnm.equals(datacenterName))
					{
						retVal = mr;
						break;
					}
				}
			}
		}
		catch (SOAPFaultException sfe)
		{
			printSoapFaultException(sfe);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return retVal;
	}

上面的方法getDatacenterTraversalSpec()就是Datacenter的遍历路径代码,然后方法getDatacenterByName(String datacenterName)才能根据获得的遍历路径进行遍历,获取相应的Datacenter的对象。

对于Datacenter的遍历路径代码,比较简单,而对于VirtualMachine或者集群(ComputeResource)之类的遍历路径代码相对复杂,之后再一一罗列。

ESX Server Inventory 结构

想要访问
vCenter 或者 ESX server 中的某个对象或者调用其方法,就必须首先根据这个对象在 inventory 中的位置找个这个对象。从上图可知,ServiceInstance 对象在 inventory 的结构树中处于根位置,因此遍历整个 inventory 或者要查找 inventory 中的某个对象,必须先从 ServiceInstance 开始。ServiceInstance 类中最重要的一个属性(property,可以理解为类的成员变量)是 content,它指向数据类型(Data Object)ServiceContent
的一个实例。ServiceContent 类含有很多该 vSphere 服务实例的重要属性和服务的引用,比如整个 inventory 的 root folder,session manager,property collector(用于查找和遍历对象),以及 EventManager, TaskManager 等。下面的类图展示了 ServiceInstance 和 ServiceContent 的部分属性。

ServiceInstance 和 ServiceContent

以上资料在网上或者vSphere
sdk自带的API或者自带的用例demo中可以找到相关的信息。本人只是挑一些重要概念陈述,接下去才主要讲解如何通过编码实现实时监控私有云的状态,譬如虚拟机cpu使用情况等性能指标。

下面罗列一些主要的关键代码(可以在vSphere
sdk自带的demo中找到相关代码),包括认证、连接、断开之类的操作。

public class MoniterWsInterface
{
	private static String url;
	private static String userName;
	private static String password;

	private static final ManagedObjectReference SVC_INST_REF = new ManagedObjectReference();
	private static VimService vimService;
	private static VimPortType vimPort;

	private static ServiceContent serviceContent;
	private static final String SVC_INST_NAME = "ServiceInstance";
	private static Boolean isConnected = false;
	private static ManagedObjectReference perfManager;
	private static ManagedObjectReference propCollectorRef;

	public MoniterWsInterface(String puserName, String ppassWord, String purl)
	{
		url = purl;
		userName = puserName;
		password = ppassWord;
	}

	private static class TrustAllTrustManager implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager
	{
		public java.security.cert.X509Certificate[] getAcceptedIssuers()
		{
			return null;
		}

		public boolean isServerTrusted(java.security.cert.X509Certificate[] certs)
		{
			return true;
		}

		public boolean isClientTrusted(java.security.cert.X509Certificate[] certs)
		{
			return true;
		}

		public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException
		{
			return;
		}

		public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException
		{
			return;
		}
	}

	private static void trustAllHttpsCertificates() throws Exception
	{
		javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
		javax.net.ssl.TrustManager tm = new TrustAllTrustManager();
		trustAllCerts[0] = tm;
		javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
		javax.net.ssl.SSLSessionContext sslsc = sc.getServerSessionContext();
		sslsc.setSessionTimeout(0);
		sc.init(null, trustAllCerts, null);
		javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
	}

	public static void connect() throws Exception
	{
		HostnameVerifier hv = new HostnameVerifier()
		{
			public boolean verify(String urlHostName, SSLSession session)
			{
				return true;
			}
		};
		trustAllHttpsCertificates();

		HttpsURLConnection.setDefaultHostnameVerifier(hv);

		SVC_INST_REF.setType(SVC_INST_NAME);
		SVC_INST_REF.setValue(SVC_INST_NAME);

		vimService = new VimService();
		vimPort = vimService.getVimPort();
		Map<String, Object> ctxt = ((BindingProvider) vimPort).getRequestContext();

		ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
		ctxt.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);

		serviceContent = vimPort.retrieveServiceContent(SVC_INST_REF);
		vimPort.login(serviceContent.getSessionManager(), userName, password, null);
		isConnected = true;

		perfManager = serviceContent.getPerfManager();
		propCollectorRef = serviceContent.getPropertyCollector();
	}

	public static void disconnect() throws Exception
	{
		if (isConnected)
		{
			vimPort.logout(serviceContent.getSessionManager());
		}
		isConnected = false;
	}

	private static void printSoapFaultException(SOAPFaultException sfe)
	{
		System.out.println("Soap fault: ");
		if (sfe.getFault().hasDetail())
		{
			System.out.println(sfe.getFault().getDetail().getFirstChild().getLocalName());
		}
		if (sfe.getFault().getFaultString() != null)
		{
			System.out.println("Message: " + sfe.getFault().getFaultString());
		}
	}
	public static void main(String[] args)
	{
		new MoniterWsInterface("xxx", "xxx", "xxx");
		try
		{
			connect();
		}
		catch (SOAPFaultException sfe)
		{
			printSoapFaultException(sfe);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				disconnect();
			}
			catch (SOAPFaultException sfe)
			{
				printSoapFaultException(sfe);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}
}

这样就可以通过相关连接信息(username,password,url)进行相关连接。

由于篇幅原因,接下来的内容在之后的文章中一一呈现。

补充:retrievePropertiesAllObjects的代码:

	private static List<ObjectContent> retrievePropertiesAllObjects(List<PropertyFilterSpec> listpfs) throws Exception
	{
		RetrieveOptions propObjectRetrieveOpts = new RetrieveOptions();
		List<ObjectContent> listobjcontent = new ArrayList<ObjectContent>();

		try
		{
			RetrieveResult rslts = vimPort.retrievePropertiesEx(propCollectorRef, listpfs, propObjectRetrieveOpts);
			if (rslts != null && rslts.getObjects() != null && !rslts.getObjects().isEmpty())
			{
				listobjcontent.addAll(rslts.getObjects());
			}
			String token = null;
			if (rslts != null && rslts.getToken() != null)
			{
				token = rslts.getToken();
			}
			while (token != null && !token.isEmpty())
			{
				rslts = vimPort.continueRetrievePropertiesEx(propCollectorRef, token);
				token = null;
				if (rslts != null)
				{
					token = rslts.getToken();
					if (rslts.getObjects() != null && !rslts.getObjects().isEmpty())
					{
						listobjcontent.addAll(rslts.getObjects());
					}
				}
			}
		}
		catch (SOAPFaultException sfe)
		{
			printSoapFaultException(sfe);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		return listobjcontent;
	}
时间: 2024-09-13 04:46:51

使用VMware VSphere WebService SDK进行开发 (一)——基本信息阐述的相关文章

使用VMware VSphere WebService SDK进行开发 (七)——获取数据中心、集群、主机、虚拟机的目录结构

在实际应用中,需要显示出数据中心(Datacenter).集群(ClusterComputeResource).主机(HostSystem).虚拟机(VirtualMachine)之间的目录关系.这里忽略VAPP以及APP. 正所谓无图无真相,先展示一张vSphere Client上的截图,以便形象的描述本文所要呈现的内容. 左边的目录树形象的展示了数据中心(Datacenter).集群(ClusterComputeResource).主机(HostSystem).虚拟机(VirtualMach

使用VMware VSphere WebService SDK进行开发 (二)——获取虚拟机cpu的使用情况

本文通过代码举例虚拟机cpu的使用情况来演示如何遍历搜寻VirtualMachine的对象,以及根据这个对象进行性能指标的见识.希望可以取到举一反三的效果. 首先下面先罗列出如何更具虚拟机的名称获得VirtualMachine的ManagedObjectReference对象. private static TraversalSpec getVmTraversalSpec() { TraversalSpec vAppToVM = new TraversalSpec(); vAppToVM.set

使用VMware VSphere WebService SDK进行开发 (六)——检测告警信息

获取告警信息相对而言比较简单点,这里先陈述告警信息的pojo类,作为存储告警信息的源头(省略getter和setter方法): public class AlarmItem { //对象 private String ObjectName; //状态 private ManagedEntityStatus overallStatus; //名称 private String alarmName; //触发时间 private Date time; //确认时间 private Date ackn

使用VMware VSphere WebService SDK进行开发 (三)——获取主机(HostSystem)的基本信息

通过前面两篇文章的了解,详细应该很快掌握的code路数,这里首先罗列如何获取主机(接下去也会成为HostSystem)的对象. private static TraversalSpec getHostSystemTraversalSpec() { SelectionSpec ss = new SelectionSpec(); ss.setName("VisitFolders"); TraversalSpec computeResourceToHostSystem = new Trave

使用VMware VSphere WebService SDK进行开发 (五)——根据虚拟机的名称获取对应主机的IP地址

在整个获取监视信息的过程中,最难获取的就是根据虚拟机的名称获得对应主机的IP地址的功能.(个人觉得比较绕,绕了好久我才找到) 首先根据虚拟机的名称获得对应主机(HostSystem)的ManagedObjectReference对象. RetrieveResult props = getRetrieveResultObjectWithProperty("VirtualMachine", "summary.runtime.host"); ManagedObjectRe

VMware 虚拟化编程(3) —VMware vSphere Web Service API 解析

目录 目录 前文列表 VMware vSphere Web Services API VMware vSphere Web Services SDK vSphere WS API 中的托管对象 Managed Object 托管对象引用 Managed Object References 托管对象属性收集器 PropertyCollector 连接 vCenter 并获取 MO 最后 前文列表 VMware 虚拟化编程(1) - VMDK/VDDK/VixDiskLib/VADP 概念简析 VM

fence vmware use vmware vSphere SDK for Perl

我们可以通过fence_vmware命令连接到vCenter来fence vCenter管理的虚拟机. 本文将简单的描述一下fence_vmware的使用, 以及/etc/cluster/cluster.conf的配置. 命令行帮助如下 : [root@digoal_02 soft_bak]# fence_vmware --help Usage: fence_vmware [options] Options: -o, --action=<action> Action: status, rebo

《VMware vSphere设计(原书第2版)》——3.1 检查管理层的组件

3.1 检查管理层的组件 什么是管理层呢?当然不是指公司的执行官或董事会.我们所说的管理层是指用于日常管理整个虚拟化基础设施的组件.本节将简要介绍vSphere的管理组件.首先从最主要的vCenter 服务器开始. VMware vCenter服务器 vCenter服务器(原名VirtualCenter服务器)是虚拟化基础设施中最关键的元素之一,是用于管理虚拟数据中心的管理应用程序.你会创建数据中心.集群.资源池.网络和数据存储:分配权限:配置告警:监控性能等.所有这些功能都是在vCenter服

VMware vSphere 关键概念理解与速查手册

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dgd2010.blog.51cto.com/1539422/1414113 此篇文章结合vCenter帮助手册和vSphere中文文档对VMware虚拟化中涉及的一些关键字或专有名词进行了部分整理,刚接触VMware虚拟化不久的朋友可以从中得到一些借鉴和提示.PS:本文概念基于VMware vSphere 5.5,同样适用于先前的vSphere发行版本. 参考: VMware