com.abiquo.nodecollector.domain.collectors.AbstractLibvirtCollector.java Source code

Java tutorial

Introduction

Here is the source code for com.abiquo.nodecollector.domain.collectors.AbstractLibvirtCollector.java

Source

/**
 * Abiquo community edition
 * cloud management application for hybrid clouds
 * Copyright (C) 2008-2010 - Abiquo Holdings S.L.
 *
 * This application is free software; you can redistribute it and/or
 * modify it under the terms of the GNU LESSER GENERAL PUBLIC
 * LICENSE as published by the Free Software Foundation under
 * version 3 of the License
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * LESSER GENERAL PUBLIC LICENSE v.3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

package com.abiquo.nodecollector.domain.collectors;

import java.util.ArrayList;
import java.util.List;

import javax.xml.xpath.XPathExpressionException;

import org.apache.commons.io.FilenameUtils;
import org.libvirt.Domain;
import org.libvirt.DomainInfo;
import org.libvirt.LibvirtException;
import org.libvirt.NodeInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.abiquo.nodecollector.aim.AimCollector;
import com.abiquo.nodecollector.constants.MessageValues;
import com.abiquo.nodecollector.domain.collectors.libvirt.LeaksFreeConnect;
import com.abiquo.nodecollector.exception.CollectorException;
import com.abiquo.nodecollector.exception.NoManagedException;
import com.abiquo.nodecollector.exception.libvirt.AimException;
import com.abiquo.nodecollector.utils.XPathUtils;
import com.abiquo.server.core.infrastructure.nodecollector.HostDto;
import com.abiquo.server.core.infrastructure.nodecollector.HostStatusEnumType;
import com.abiquo.server.core.infrastructure.nodecollector.ResourceEnumType;
import com.abiquo.server.core.infrastructure.nodecollector.ResourceType;
import com.abiquo.server.core.infrastructure.nodecollector.VirtualDiskEnumType;
import com.abiquo.server.core.infrastructure.nodecollector.VirtualSystemCollectionDto;
import com.abiquo.server.core.infrastructure.nodecollector.VirtualSystemDto;
import com.abiquo.server.core.infrastructure.nodecollector.VirtualSystemStatusEnumType;

/**
 * Abstract class which provides common information collection for Libvirt-supported Hypervisors (In
 * our case KVM and XEN).
 * 
 * @author jdevesa
 */
public abstract class AbstractLibvirtCollector extends AbstractCollector {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractLibvirtCollector.class);

    private LeaksFreeConnect connection;

    protected AimCollector aimcollector;

    // private LeaksFreeConnect login() throws CollectorException
    // {
    // try
    // {
    // return new LeaksFreeConnect(getConnectionURL());
    // }
    // catch (LibvirtException e)
    // {
    // throw new CollectorException(MessageValues.CONN_EXCP_I, e);
    // }
    // }
    //
    // private void logout(LeaksFreeConnect conn)
    // {
    // try
    // {
    // conn.close();
    // }
    // catch (LibvirtException e)
    // {
    // e.printStackTrace();
    // }
    // }

    @Override
    public HostDto getHostInfo() throws CollectorException {
        final int KBYTE = 1024;
        final HostDto hostInfo = new HostDto();

        // LeaksFreeConnect conn = login();

        try {
            final NodeInfo nodeInfo = connection.nodeInfo();
            hostInfo.setName(connection.getHostName());
            hostInfo.setCpu(Long.valueOf(nodeInfo.cores));
            hostInfo.setRam(nodeInfo.memory * KBYTE);
            hostInfo.setHypervisor(getHypervisorType().getValue());
            hostInfo.setVersion(String.valueOf(connection.getVersion()));

            List<ResourceType> datastores = aimcollector.getDatastores();

            hostInfo.getResources().addAll(aimcollector.getNetInterfaces());
            hostInfo.setInitiatorIQN(aimcollector.getInitiatorIQN());

            try {
                // [ABICLOUDPREMIUM-345] Node collector mustn't return datastores NFS equal to AM.
                // TODO Depends on [ABICLOUDPREMIUM-365]
                // datastores = removeRepositoryDatastore(datastores, repositoryLocation);

                hostInfo.getResources().addAll(datastores);

                checkPhysicalState();
                hostInfo.setStatus(HostStatusEnumType.MANAGED);
            } catch (NoManagedException e) {
                hostInfo.setStatus(HostStatusEnumType.NOT_MANAGED);
                hostInfo.setStatusInfo(e.getMessage());
            }

        } catch (LibvirtException e) {
            LOGGER.error("Unhandled exception :", e);
            throw new CollectorException(MessageValues.COLL_EXCP_PH, e);
        } catch (AimException e) {
            LOGGER.error("Unhandled exception :", e);
            throw new CollectorException(e.getMessage(), e);
        }
        // finally
        // {
        // logout(conn);
        // }

        return hostInfo;
    }

    @Override
    public VirtualSystemCollectionDto getVirtualMachines() throws CollectorException {
        final VirtualSystemCollectionDto vmc = new VirtualSystemCollectionDto();
        final List<Domain> listOfDomains = new ArrayList<Domain>();

        try {
            // Defined domains are the closed ones!
            for (String domainValue : connection.listDefinedDomains()) {
                if (domainValue != null) // Why null domains are returned?
                {
                    listOfDomains.add(connection.domainLookupByName(domainValue));
                }
            }
            // Domains are the started ones
            for (int domainInt : connection.listDomains()) {
                listOfDomains.add(connection.domainLookupByID(domainInt));
            }

            // Create the list of Virtual Systems from the recovered domains
            for (Domain domain : listOfDomains) {
                if (!isDomain0(domain)) {
                    vmc.getVirtualSystems().add(createVirtualSystemFromDomain(domain));
                }
            }
        } catch (LibvirtException e1) {
            LOGGER.error("Unhandled exception :", e1);
            throw new CollectorException(e1.getMessage(), e1);
        } catch (XPathExpressionException e) {
            LOGGER.error("Unhandled exception :", e);
            throw new CollectorException(e.getMessage(), e);
        }

        return vmc;
    }

    protected void checkPhysicalState() throws NoManagedException {
        try {
            aimcollector.checkAIM();
        } catch (AimException e) {
            throw new NoManagedException(e.getMessage(), e);
        }
    }

    @Override
    public void disconnect() throws CollectorException {
        try {
            if (getConnection() != null) {
                getConnection().close();
            }
        } catch (LibvirtException e) {
            LOGGER.error("Unhandled exception when disconnect:", e);
            throw new CollectorException(MessageValues.CONN_EXCP_III, e);
        }
    }

    /**
     * @param domain a domain defined by libvirt.
     * @return a {@link VirtualSystem} object
     * @throws LibvirtException can be thrown when connecting to libvirt
     * @throws XPathExpressionException can be thrown parsing the libvirt response
     */
    private VirtualSystemDto createVirtualSystemFromDomain(final Domain domain)
            throws LibvirtException, XPathExpressionException {

        final int KBYTE = 1024;
        final DomainInfo domainInfo = domain.getInfo();
        final String domainXML = domain.getXMLDesc(0);

        final VirtualSystemDto vSys = new VirtualSystemDto();
        vSys.setRam(domainInfo.memory * KBYTE);
        vSys.setCpu(Long.valueOf(domainInfo.nrVirtCpu));
        vSys.setName(domain.getName());
        vSys.setUuid(domain.getUUIDString());

        // If autoport is enabled, set port to -1 to indicate that remote access will not be
        // available
        String autoport = XPathUtils.getValue("//graphics/@autoport", domainXML);
        if (autoport != null && autoport.equalsIgnoreCase("yes")) {
            vSys.setVport(-1L);
        } else {
            // Evaluate the libvirt XML desc of the domain to get the remote display port.
            String vPortString = XPathUtils.getValue("//graphics/@port", domainXML);
            if (vPortString == null || vPortString.isEmpty()) {
                vSys.setVport(-1L);
            } else {
                Long vPort = Long.valueOf(vPortString);
                vSys.setVport(vPort <= 0 ? -1 : vPort);
            }
        }

        // Evaluate the libvirt XML desc of the domain to get the image files
        // using the XPath features

        // final List<String> imageValues = XPathUtils.getValues("//disk/source/@file",
        // domainXML);
        // for (String imageValue : imageValues)
        // {
        // vSys.getResources().add(createDiskFromImagePath(imageValue));
        // }

        NodeList systemdisk = XPathUtils.getNodes("//disk[target[@dev='hda']]/source", domainXML);
        if (systemdisk.item(0) != null) {
            Node image = systemdisk.item(0).getAttributes().getNamedItem("file");
            if (image != null) {
                vSys.getResources().add(createDiskFromImagePath(image.getNodeValue()));
            } else {
                image = systemdisk.item(0).getAttributes().getNamedItem("dev");
                vSys.getResources().add(createDiskFromVolumePath(image.getNodeValue()));
            }
        }

        // Homogenize the status
        switch (domainInfo.state) {
        case VIR_DOMAIN_RUNNING:
        case VIR_DOMAIN_BLOCKED:
            vSys.setStatus(VirtualSystemStatusEnumType.ON);
            break;

        case VIR_DOMAIN_PAUSED:
            vSys.setStatus(VirtualSystemStatusEnumType.PAUSED);
            break;

        default:
            vSys.setStatus(VirtualSystemStatusEnumType.OFF);
            break;
        }

        return vSys;
    }

    /**
     * Create a {@link Disk} objet from an image value.
     * 
     * @param imagePath image where the disk is stored
     * @return a Disk object filled with the information
     */
    private ResourceType createDiskFromImagePath(final String imagePath) {

        final ResourceType currentHardDisk = new ResourceType();
        currentHardDisk.setResourceType(ResourceEnumType.HARD_DISK);
        currentHardDisk.setAddress(imagePath);
        try {

            long diskSize = aimcollector.getDiskFileSize(imagePath);
            currentHardDisk.setUnits(diskSize);

        } catch (AimException e) {
            currentHardDisk.setUnits(0L);
        }
        currentHardDisk.setResourceSubType(VirtualDiskEnumType.UNKNOWN.value());
        currentHardDisk.setConnection(FilenameUtils.getFullPathNoEndSeparator(imagePath));
        return currentHardDisk;

    }

    /**
     * Create a {@link Disk} objet from an image value.
     * 
     * @param imagePath image where the disk is stored
     * @return a Disk object filled with the information
     */
    private ResourceType createDiskFromVolumePath(final String imagePath) {

        final ResourceType currentHardDisk = new ResourceType();
        currentHardDisk.setResourceType(ResourceEnumType.VOLUME_DISK);
        currentHardDisk.setAddress(""); // Datastore directory
        try {

            long diskSize = aimcollector.getDiskFileSize(imagePath);
            currentHardDisk.setUnits(diskSize);

        } catch (AimException e) {
            currentHardDisk.setUnits(0L);
        }
        currentHardDisk.setResourceSubType(VirtualDiskEnumType.STATEFUL.value());
        currentHardDisk.setConnection(""); // Datastore root path
        return currentHardDisk;

    }

    /**
     * Returns true if given domain is "Domain-0"
     * 
     * @param domain to evaluate
     * @return true if given domain is "Domain-0"
     * @throws LibvirtException exception
     */
    protected abstract boolean isDomain0(Domain domain) throws LibvirtException;

    public LeaksFreeConnect getConnection() {
        return connection;
    }

    public void setConnection(final LeaksFreeConnect conn) {
        this.connection = conn;
    }
}