Author: pnguyen Date: 2010-05-25 16:18:22 -0700 (Tue, 25 May 2010) New Revision: 14620 URL: http://svn.hyperic.org/?view=rev&root=Hyperic+HQ&revision=14620 Modified: trunk/plugins/vsphere/src/org/hyperic/hq/plugin/vsphere/VCenterPlatformDetector.java trunk/src/org/hyperic/hq/authz/server/session/ResourceManagerEJBImpl.java trunk/src/org/hyperic/hq/hqu/rendit/helpers/ResourceHelper.groovy Log: vsphere plugin - sync resource edges for vcenters, hosts, and vms Modified: trunk/plugins/vsphere/src/org/hyperic/hq/plugin/vsphere/VCenterPlatformDetector.java =================================================================== --- trunk/plugins/vsphere/src/org/hyperic/hq/plugin/vsphere/VCenterPlatformDetector.java 2010-05-25 21:36:14 UTC (rev 14619) +++ trunk/plugins/vsphere/src/org/hyperic/hq/plugin/vsphere/VCenterPlatformDetector.java 2010-05-25 23:18:22 UTC (rev 14620) @@ -38,13 +38,19 @@ import org.hyperic.hq.hqapi1.AgentApi; import org.hyperic.hq.hqapi1.HQApi; import org.hyperic.hq.hqapi1.ResourceApi; +import org.hyperic.hq.hqapi1.ResourceEdgeApi; import org.hyperic.hq.hqapi1.XmlUtil; import org.hyperic.hq.hqapi1.types.Agent; import org.hyperic.hq.hqapi1.types.AgentResponse; import org.hyperic.hq.hqapi1.types.AgentsResponse; import org.hyperic.hq.hqapi1.types.Resource; +import org.hyperic.hq.hqapi1.types.ResourceConfig; +import org.hyperic.hq.hqapi1.types.ResourceEdge; +import org.hyperic.hq.hqapi1.types.ResourceFrom; +import org.hyperic.hq.hqapi1.types.ResourceProperty; import org.hyperic.hq.hqapi1.types.ResourcePrototype; import org.hyperic.hq.hqapi1.types.ResourcePrototypeResponse; +import org.hyperic.hq.hqapi1.types.ResourceTo; import org.hyperic.hq.hqapi1.types.ResourcesResponse; import org.hyperic.hq.hqapi1.types.Response; import org.hyperic.hq.hqapi1.types.ResponseStatus; @@ -88,6 +94,7 @@ private static final String AGENT_IP = "agent.setup.agentIP"; private static final String AGENT_PORT = "agent.setup.agentPort"; + private static final String VC_TYPE = "VMware vCenter"; private static final String VM_TYPE = "VMware vSphere VM"; private static final String HOST_TYPE = "VMware vSphere Host"; private static final String POOL_TYPE = "VMware vSphere Resource Pool"; @@ -219,14 +226,16 @@ return type; } - private VSphereResource discoverVM(VSphereUtil vim, - VirtualMachine vm) + private VSphereResource discoverVM(VirtualMachine vm) throws Exception { - VirtualMachineRuntimeInfo runtime = vm.getRuntime(); - VirtualMachineConfigInfo info = vm.getConfig(); + if (info.isTemplate()) { + return null; //filter out template VMs + } + + VirtualMachineRuntimeInfo runtime = vm.getRuntime(); GuestInfo guest = vm.getGuest(); ResourcePool pool = vm.getResourcePool(); @@ -321,7 +330,7 @@ continue; //filter out template VMs } try { - VSphereResource platform = discoverVM(vim, vm); + VSphereResource platform = discoverVM(vm); if (platform == null) { continue; } @@ -408,7 +417,7 @@ return resources; } - private VSphereResource discoverHost(VSphereUtil vim, HostSystem host) + private VSphereResource discoverHost(HostSystem host) throws Exception { HostConfigInfo info = host.getConfig(); @@ -491,7 +500,7 @@ throws IOException, PluginException { List<Resource> resources = new ArrayList<Resource>(); - ResourcePrototype type = getResourceType(HOST_TYPE); + ResourcePrototype hostType = getResourceType(HOST_TYPE); try { ManagedEntity[] hosts = vim.find(VSphereUtil.HOST_SYSTEM); @@ -505,13 +514,27 @@ HostSystem host = (HostSystem)hosts[i]; try { - VSphereResource platform = discoverHost(vim, host); + VSphereResource platform = discoverHost(host); if (platform == null) { continue; } - platform.setResourcePrototype(type); + platform.setResourcePrototype(hostType); platform.setAgent(agent); mergeVSphereConfig(platform); + + // TODO: Uncomment and remove discoverVirtualMachines + /* + VirtualMachine[] hostVms = host.getVms(); + for (int v=0; v<hostVms.length; v++) { + VSphereResource vm = discoverVM(hostVms[v]); + if (vm != null) { + vm.setResourcePrototype(vmType); + vm.setAgent(agent); + mergeVSphereConfig(vm); + resources.add(vm); + } + */ + List<Resource> rpools = pools.get(host.getName()); if (rpools != null) { platform.getResource().addAll(rpools); @@ -554,5 +577,124 @@ } finally { VSphereUtil.dispose(vim); } + + if (!isDump) { + syncResourceEdges(); + } } + + private void syncResourceEdges() + throws IOException, PluginException { + ResourceApi rApi = getApi().getResourceApi(); + ResourceEdgeApi reApi = getApi().getResourceEdgeApi(); + + List<ResourceEdge> edges = new ArrayList<ResourceEdge>(); + + Resource vCenter = null; + ResourcePrototype vcType = getResourceType(VC_TYPE); + ResourcesResponse vcResponse = rApi.getResources(vcType, true, false); + assertSuccess(vcResponse, "Getting all " + VC_TYPE, false); + + for (Resource r : vcResponse.getResource()) { + for (ResourceConfig c : r.getResourceConfig()) { + if (VSphereUtil.PROP_URL.equals(c.getKey())) { + if (c.getValue().equals(VSphereUtil.getURL(this.props))) { + vCenter = r; + break; + } + } + } + } + + if (vCenter == null) { + if (log.isDebugEnabled()) { + log.debug("No VMware vCenter server found with url=" + + VSphereUtil.getURL(this.props)); + } + return; + } + + ResourcePrototype hostType = getResourceType(HOST_TYPE); + ResourcesResponse hostResponse = rApi.getResources(hostType, true, false); + assertSuccess(hostResponse, "Getting all " + HOST_TYPE, false); + + ResourceEdge edge = new ResourceEdge(); + ResourceFrom from = new ResourceFrom(); + ResourceTo to = new ResourceTo(); + + for (Resource r : hostResponse.getResource()) { + for (ResourceConfig c : r.getResourceConfig()) { + if (VSphereUtil.PROP_URL.equals(c.getKey())) { + if (c.getValue().equals(VSphereUtil.getURL(this.props))) { + to.getResource().add(r); + } + } + } + } + + if (log.isDebugEnabled()) { + log.debug("vc name=" + vCenter.getName() + + ", resourceId=" + vCenter.getId() + + ", host size=" + to.getResource().size()); + } + + from.setResource(vCenter); + edge.setRelation("virtual"); + edge.setResourceFrom(from); + edge.setResourceTo(to); + edges.add(edge); + + StatusResponse syncResponse = reApi.syncResourceEdges(edges); + assertSuccess(syncResponse, "Sync vCenter and host edges", false); + + ResourcePrototype vmType = getResourceType(VM_TYPE); + ResourcesResponse vmResponse = rApi.getResources(vmType, true, false); + assertSuccess(vmResponse, "Getting all " + VM_TYPE, false); + + Map<String, List<Resource>> hostVmMap = new HashMap<String, List<Resource>>(); + + for (Resource r : vmResponse.getResource()) { + String esxHost = null; + for (ResourceProperty p : r.getResourceProperty()) { + if ("esxHost".equals(p.getKey())) { + esxHost = p.getValue(); + break; + } + } + List<Resource> vmResources = hostVmMap.get(esxHost); + if (vmResources == null) { + vmResources = new ArrayList<Resource>(); + hostVmMap.put(esxHost, vmResources); + } + vmResources.add(r); + } + + edges.clear(); + + for (Resource r : hostResponse.getResource()) { + ResourceFrom parent = new ResourceFrom(); + parent.setResource(r); + + ResourceTo children = new ResourceTo(); + List<Resource> vmResources = hostVmMap.get(r.getName()); + if (vmResources != null) { + children.getResource().addAll(vmResources); + } + + ResourceEdge rEdge = new ResourceEdge(); + rEdge.setRelation("virtual"); + rEdge.setResourceFrom(parent); + rEdge.setResourceTo(children); + edges.add(rEdge); + + if (log.isDebugEnabled()) { + log.debug("host name=" + r.getName() + + ", resourceId=" + r.getId() + + ", vm size=" + children.getResource().size()); + } + } + + syncResponse = reApi.syncResourceEdges(edges); + assertSuccess(syncResponse, "Sync host and VM edges", false); + } } Modified: trunk/src/org/hyperic/hq/authz/server/session/ResourceManagerEJBImpl.java =================================================================== --- trunk/src/org/hyperic/hq/authz/server/session/ResourceManagerEJBImpl.java 2010-05-25 21:36:14 UTC (rev 14619) +++ trunk/src/org/hyperic/hq/authz/server/session/ResourceManagerEJBImpl.java 2010-05-25 23:18:22 UTC (rev 14620) @@ -6,7 +6,7 @@ * normal use of the program, and does *not* fall under the heading of * "derived work". * - * Copyright (C) [2004-2009], Hyperic, Inc. + * Copyright (C) [2004-2010], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify @@ -40,6 +40,8 @@ import javax.ejb.FinderException; import javax.ejb.SessionBean; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.hyperic.dao.DAOFactory; import org.hyperic.hibernate.PageInfo; import org.hyperic.hq.appdef.ConfigResponseDB; @@ -98,6 +100,7 @@ */ public class ResourceManagerEJBImpl extends AuthzSession implements SessionBean { + private final Log log = LogFactory.getLog(ResourceManagerEJBImpl.class); private Pager resourceTypePager = null; private ResourceEdgeDAO getResourceEdgeDAO() { @@ -798,14 +801,116 @@ AppdefEntityID[] children, boolean deleteExisting) throws PermissionException, ResourceEdgeCreateException { - - if (relation == null - || !relation.getId().equals(AuthzConstants.RELATION_NETWORK_ID)) { + + if (relation == null) { + throw new ResourceEdgeCreateException("Resource relation is null"); + } + + if (relation.getId().equals(AuthzConstants.RELATION_NETWORK_ID)) { + createNetworkResourceEdges(subject, + relation, + parent, + children, + deleteExisting); + } else if (relation.getId().equals(AuthzConstants.RELATION_VIRTUAL_ID)) { + createVirtualResourceEdges(subject, + relation, + parent, + children, + false); + } else { throw new ResourceEdgeCreateException( - "Only " + AuthzConstants.ResourceEdgeNetworkRelation - + " resource relationships are supported."); + "Unsupported resource relation: " + + relation.getName()); } + } + + private void createVirtualResourceEdges(AuthzSubject subject, + ResourceRelation relation, + AppdefEntityID parent, + AppdefEntityID[] children, + boolean deleteExisting) + throws PermissionException, ResourceEdgeCreateException { + //TODO: Add VM/host verification check ??? + Resource parentResource = findResource(parent); + + if (parentResource != null + && !parentResource.isInAsyncDeleteState() + && children != null + && children.length > 0) { + + try { + if (deleteExisting) { + removeResourceEdges(subject, relation, parentResource); + } + + ResourceEdgeDAO eDAO = getResourceEdgeDAO(); + Collection edges = findResourceEdges(relation, parentResource); + ResourceEdge existing = null; + Resource childResource = null; + + if (edges.isEmpty()) { + // create self-edge for parent of virtual hierarchy + eDAO.create(parentResource, parentResource, 0, relation); + } + for (int i=0; i< children.length; i++) { + //TODO: Add VM/host verification check ??? + childResource = findResource(children[i]); + + // Check if child resource already exists in VM hierarchy + // TODO: This needs to be optimized + existing = getParentResourceEdge(childResource, relation); + + if (existing != null) { + Resource existingParent = existing.getFrom(); + if (existingParent.getId().equals(parentResource.getId())) { + // already exists with same parent, so skip + log.info("Skipping. Virtual resource edge already exists: from id=" + + parentResource.getId() + + ", to id=" + childResource.getId()); + continue; + } else { + // already exists with different parent + // TODO: vMotion occurred + + log.info("Virtual resource edge exists with another resource: from id=" + + existingParent.getId() + + ", to id=" + childResource.getId() + + ", target from id=" + parentResource.getId()); + continue; + } + } + + if (childResource != null && !childResource.isInAsyncDeleteState()) { + eDAO.create(parentResource, childResource, 1, relation); + eDAO.create(childResource, parentResource, -1, relation); + + Collection ancestors = eDAO.findAncestorEdges(parentResource, relation); + + for (Iterator a=ancestors.iterator(); a.hasNext();) { + ResourceEdge ancestorEdge = (ResourceEdge)a.next(); + + int distance = ancestorEdge.getDistance() - 1; + + eDAO.create(childResource, ancestorEdge.getTo(), distance, relation); + eDAO.create(ancestorEdge.getTo(), childResource, -distance, relation); + } + } + } + } catch (Throwable t) { + throw new ResourceEdgeCreateException(t); + } + } + } + + private void createNetworkResourceEdges(AuthzSubject subject, + ResourceRelation relation, + AppdefEntityID parent, + AppdefEntityID[] children, + boolean deleteExisting) + throws PermissionException, ResourceEdgeCreateException { + if (parent == null || !parent.isPlatform()) { throw new ResourceEdgeCreateException("Only platforms are supported."); } Modified: trunk/src/org/hyperic/hq/hqu/rendit/helpers/ResourceHelper.groovy =================================================================== --- trunk/src/org/hyperic/hq/hqu/rendit/helpers/ResourceHelper.groovy 2010-05-25 21:36:14 UTC (rev 14619) +++ trunk/src/org/hyperic/hq/hqu/rendit/helpers/ResourceHelper.groovy 2010-05-25 23:18:22 UTC (rev 14620) @@ -18,6 +18,7 @@ import org.hyperic.hq.authz.server.session.ResourceSortField import org.hyperic.hq.authz.server.session.Resource import org.hyperic.hq.authz.server.session.ResourceGroup +import org.hyperic.hq.authz.server.session.ResourceRelation import org.hyperic.hq.bizapp.server.session.AppdefBossEJBImpl as AppdefBoss import org.hyperic.util.pager.PageControl import org.hyperic.hq.authz.server.session.ResourceGroup.ResourceGroupCreateInfo @@ -452,13 +453,17 @@ } void createResourceEdges(String resourceRelation, AppdefEntityID parent, AppdefEntityID[] children, boolean deleteExisting) { - if (!resourceRelation.equals(AuthzConstants.ResourceEdgeNetworkRelation)) { - throw new IllegalArgumentException('Only ' - + AuthzConstants.ResourceEdgeNetworkRelation - + ' resource relationships are supported.') + ResourceRelation relation = null; + if (AuthzConstants.ResourceEdgeNetworkRelation.equals(resourceRelation)) { + relation = rman.getNetworkRelation() + } else if (AuthzConstants.ResourceEdgeVirtualRelation.equals(resourceRelation)) { + relation = rman.getVirtualRelation() + } else { + throw new IllegalArgumentException( + 'Unsupported resource relation: ' + resourceRelation) } - rman.createResourceEdges(user, rman.getNetworkRelation(), parent, children, deleteExisting) + rman.createResourceEdges(user, relation, parent, children, deleteExisting) } void removeResourceEdges(String resourceRelation, Resource resource) { |