com.vmware.bdd.entity.NodeEntity.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.bdd.entity.NodeEntity.java

Source

/***************************************************************************
 * Copyright (c) 2012-2015 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.bdd.entity;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.*;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.log4j.Logger;

import com.vmware.bdd.apitypes.IpConfigInfo;
import com.vmware.bdd.apitypes.NetConfigInfo.NetTrafficType;
import com.vmware.bdd.apitypes.NodeRead;
import com.vmware.bdd.apitypes.NodeStatus;
import com.vmware.bdd.apitypes.StorageRead.DiskType;
import com.vmware.bdd.exception.BddException;
import com.vmware.bdd.spectypes.NicSpec;
import com.vmware.bdd.utils.AuAssert;
import com.vmware.bdd.utils.CommonUtil;
import com.vmware.bdd.utils.Constants;

/**
 * Hadoop Node Entity class: describes hadoop node info
 * 
 */

@NamedNativeQueries({
        @NamedNativeQuery(name = "node.countByNodeGroup", query = "select count(n.id) from node as n where n.node_group_id=:nodeGroupId") })

@Entity
@SequenceGenerator(name = "IdSequence", sequenceName = "node_seq", allocationSize = 1)
@Table(name = "node")
public class NodeEntity extends EntityBase {
    private static final Logger logger = Logger.getLogger(NodeEntity.class);
    @Column(name = "vm_name", unique = true, nullable = false)
    private String vmName;

    @Column(name = "moid", unique = true)
    private String moId;

    @Column(name = "rack")
    private String rack;

    @Column(name = "host_name")
    private String hostName;

    // vm status, poweredOn/poweredOff
    @Enumerated(EnumType.STRING)
    @Column(name = "status")
    private NodeStatus status = NodeStatus.NOT_EXIST;

    // this field means VM status changed from powered on to powered off or vice visa.
    // if status changed is true, when user query status, will start a query to Ironfan
    // to get VM bootstrap status
    @Column(name = "power_status_changed")
    private boolean powerStatusChanged;

    @Column(name = "action")
    private String action;

    @Column(name = "action_failed")
    private boolean actionFailed;

    @Column(name = "error_message")
    private String errMessage;

    @Column(name = "guest_host_name")
    private String guestHostName;

    @Column(name = "cpu_number")
    private Integer cpuNum;

    @Column(name = "memory")
    private Long memorySize;

    @Column(name = "version")
    private String version;

    @ManyToOne
    @JoinColumn(name = "node_group_id")
    private NodeGroupEntity nodeGroup;

    @ManyToOne
    @JoinColumn(name = "vc_rp_id")
    private VcResourcePoolEntity vcRp;

    @OneToMany(mappedBy = "nodeEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @OrderBy("id")
    private Set<DiskEntity> disks;

    @OneToMany(mappedBy = "nodeEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<NicEntity> nics;

    public NodeEntity() {
        this.disks = new HashSet<DiskEntity>();
        this.nics = new HashSet<NicEntity>();
    }

    public NodeEntity(String vmName, String rack, String hostName, NodeStatus status) {
        super();
        this.vmName = vmName;
        this.rack = rack;
        this.hostName = hostName;
        this.status = status;
        this.disks = new HashSet<DiskEntity>();
        this.nics = new HashSet<NicEntity>();
    }

    public static List<DiskEntity> toDiskEntityList(Collection<DiskEntity> diskEntityCollection) {
        ArrayList<DiskEntity> diskSpecArrayList = new ArrayList<>();

        for (DiskEntity entity : diskEntityCollection) {
            diskSpecArrayList.add(entity);
        }

        return diskSpecArrayList;
    }

    public static void sortDiskOrder(List<DiskEntity> diskSpecs) {
        //ensure the order by entity Id
        Collections.sort(diskSpecs, new Comparator<DiskEntity>() {
            @Override
            public int compare(DiskEntity o1, DiskEntity o2) {
                return Long.compare(o1.getId(), o2.getId());
            }
        });
    }

    public List<String> getVolumns() {
        List<String> volumns = new ArrayList<String>();
        if (disks == null || disks.size() < 1) {
            return volumns;
        }
        List<DiskEntity> sortedDisks = new ArrayList<>();
        sortedDisks.addAll(disks);
        sortDiskOrder(sortedDisks);

        for (DiskEntity disk : sortedDisks) {
            if (DiskType.DATA_DISK.getType().equals(disk.getDiskType())
                    || DiskType.SWAP_DISK.getType().equals(disk.getDiskType()))
                volumns.add(disk.getDiskType() + ":" + disk.getHardwareUUID());
        }
        return volumns;
    }

    public List<String> getDataVolumnsMountPoint() {
        List<DiskEntity> sortedDisks = new ArrayList<>();
        sortedDisks.addAll(disks);
        sortDiskOrder(sortedDisks);

        //Todo(qjin): need to check
        List<String> mountPoints = new ArrayList<String>();
        int i = 0;
        for (DiskEntity disk : sortedDisks) {
            if (DiskType.DATA_DISK.getType().equals(disk.getDiskType())) {
                //Todo(qjin): when will the uuid be null?
                if (disk.getHardwareUUID() == null) {
                    continue;
                }
                mountPoints.add("/mnt/data" + i++);
            }
        }
        return mountPoints;
    }

    public String getGuestHostName() {
        return guestHostName;
    }

    public void setGuestHostName(String guestHostName) {
        this.guestHostName = guestHostName;
    }

    public boolean isPowerStatusChanged() {
        return powerStatusChanged;
    }

    public void setPowerStatusChanged(boolean powerStatusChanged) {
        this.powerStatusChanged = powerStatusChanged;
    }

    public String getVmName() {
        return vmName;
    }

    public void setVmName(String vmName) {
        this.vmName = vmName;
    }

    public String getMoId() {
        return moId;
    }

    public void setMoId(String moId) {
        this.moId = moId;
    }

    public String getRack() {
        return rack;
    }

    public void setRack(String rack) {
        this.rack = rack;
    }

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
    }

    public NodeStatus getStatus() {
        return status;
    }

    public void setUnavailableConnection() {
        this.status = NodeStatus.DISCONNECTED;
        logger.debug("node " + getVmName() + " status changed to " + status);
    }

    public boolean isDisconnected() {
        return (this.status == NodeStatus.DISCONNECTED);
    }

    /*
     * This method will compare the setting status with existing status.
     * If they are different, powerChanged field will be set accordingly.
     * To turn off statusChanged, user need to call setStatusChanged explicitly.
     * 
     */
    public void setStatus(NodeStatus status) {
        if (status.ordinal() >= NodeStatus.POWERED_ON.ordinal()
                && this.status.ordinal() >= NodeStatus.POWERED_ON.ordinal()) {
            if (status.ordinal() > this.status.ordinal()) {
                this.status = status;
                logger.debug("node " + getVmName() + " status changed to " + status);
            }
            return;
        } else if (status.ordinal() <= NodeStatus.POWERED_OFF.ordinal()
                && this.status.ordinal() <= NodeStatus.POWERED_OFF.ordinal()) {
            // the new status and old status are in same range, both powered on, or both powered off status
            // don't think that power status is changed
            if (this.status != status) {
                this.status = status;
                logger.debug("node " + getVmName() + " status changed to " + status);
            }
            return;
        }

        if (this.status != status) {
            powerStatusChanged = true;
            logger.debug("node " + getVmName() + " status changed to " + status);
            this.status = status;
        }
    }

    public void setStatus(NodeStatus status, boolean validation) {
        if (validation) {
            setStatus(status);
        } else {
            logger.debug("Set node " + getVmName() + " status to" + status + " without validation");
            this.status = status;
        }
    }

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        if (!(new EqualsBuilder().append(this.action, action).isEquals())) {
            logger.debug("node " + getVmName() + " action changed to " + action);
            this.action = action;
        }
    }

    public NicEntity getPrimaryMgtNic() {
        if (nics == null || nics.isEmpty()) {
            return null;
        }
        for (NicEntity nicEntity : nics) {
            for (NicSpec.NetTrafficDefinition netDef : nicEntity.getNetTrafficDefs()) {
                if (netDef.getTrafficType().equals(NetTrafficType.MGT_NETWORK) && netDef.getIndex() == 0) {
                    return nicEntity;
                }
            }
        }
        return (NicEntity) nics.toArray()[0];
    }

    public String getPrimaryMgtIpV4() {
        NicEntity nicEntity = getPrimaryMgtNic();
        if (nicEntity == null) {
            return Constants.NULL_IPV4_ADDRESS;
        }
        return nicEntity.getIpv4Address();
    }

    /**
     * @return the cpuNum
     */
    public Integer getCpuNum() {
        return cpuNum;
    }

    /**
     * @param cpuNum
     *           the cpuNum to set
     */
    public void setCpuNum(Integer cpuNum) {
        this.cpuNum = cpuNum;
    }

    /**
     * @return the memorySize
     */
    public Long getMemorySize() {
        return memorySize;
    }

    /**
     * @param memorySize
     *           the memorySize to set
     */
    public void setMemorySize(Long memorySize) {
        this.memorySize = memorySize;
    }

    public NodeGroupEntity getNodeGroup() {
        return nodeGroup;
    }

    public void setNodeGroup(NodeGroupEntity nodeGroup) {
        this.nodeGroup = nodeGroup;
    }

    public VcResourcePoolEntity getVcRp() {
        return vcRp;
    }

    public void setVcRp(VcResourcePoolEntity vcRp) {
        this.vcRp = vcRp;
    }

    public List<String> getDatastoreNameList() {
        Set<String> datastores = new HashSet<String>(disks.size());
        for (DiskEntity disk : disks) {
            datastores.add(disk.getDatastoreName());
        }
        return new ArrayList<String>(datastores);
    }

    public Set<DiskEntity> getDisks() {
        return disks;
    }

    public void setDisks(Set<DiskEntity> disks) {
        this.disks = disks;
    }

    public void copy(NodeEntity newNode) {
        this.status = newNode.getStatus();
        this.action = newNode.getAction();
        this.memorySize = newNode.getMemorySize();
        this.cpuNum = newNode.getCpuNum();

        if (newNode.getRack() != null) {
            this.rack = newNode.getRack();
        }
        if (newNode.getHostName() != null) {
            this.hostName = newNode.getHostName();
        }
        if (newNode.getMoId() != null) {
            this.moId = newNode.getMoId();
        }
        if (newNode.getVcRp() != null) {
            this.vcRp = newNode.getVcRp();
        }

        if (newNode.getDisks() != null && !newNode.getDisks().isEmpty()) {
            if (this.disks == null)
                this.disks = new HashSet<>(newNode.disks.size());

            for (DiskEntity disk : newNode.getDisks()) {
                DiskEntity clone = disk.copy(disk);
                clone.setNodeEntity(this);
                this.disks.add(clone);
            }
        }
    }

    public Set<String> fetchAllPortGroups() {
        return fetchPortGroupToIpMap().keySet();
    }

    public Map<String, String> fetchPortGroupToIpMap() {
        Map<String, String> pgToIpMap = new HashMap<String, String>();
        if (nics != null && !nics.isEmpty()) {
            for (NicEntity nicEntity : nics) {
                pgToIpMap.put(nicEntity.getNetworkEntity().getPortGroup(), nicEntity.getIpv4Address());
            }
        }
        return pgToIpMap;
    }

    public boolean nicsReady() {
        if (nics == null || nics.isEmpty()) {
            return false;
        }

        for (NicEntity nicEntity : nics) {
            if (!nicEntity.isReady()) {
                return false;
            }
        }
        return true;
    }

    public void resetNicsInfo() {
        if (nics == null || nics.isEmpty()) {
            return;
        }

        for (NicEntity nicEntity : nics) {
            nicEntity.setConnected(false);
            nicEntity.setIpv4Address(Constants.NULL_IPV4_ADDRESS);
            nicEntity.setIpv6Address(Constants.NULL_IPV6_ADDRESS);
        }
    }

    public NicEntity findNic(NetworkEntity networkEntity) {
        AuAssert.check(networkEntity != null);
        for (NicEntity nicEntity : nics) {
            if (nicEntity.getNetworkEntity() != null && nicEntity.getNetworkEntity().equals(networkEntity)) {
                return nicEntity;
            }
        }
        return null;
    }

    public DiskEntity findDisk(String diskName) {
        AuAssert.check(diskName != null && !diskName.isEmpty() && this.disks != null);
        for (DiskEntity disk : this.disks) {
            if (disk.getName().equals(diskName))
                return disk;
        }

        return null;
    }

    public DiskEntity findSystemDisk() {
        AuAssert.check(this.disks != null);
        for (DiskEntity disk : this.disks) {
            if (DiskType.SYSTEM_DISK.getType().equals(disk.getDiskType()))
                return disk;
        }

        return null;
    }

    public boolean isObsoleteNode() {
        // if resize failed, some node is out of cluster scope.
        try {
            long index = CommonUtil.getVmIndex(vmName);
            if (index < nodeGroup.getDefineInstanceNum()) {
                return false;
            } else {
                return true;
            }
        } catch (BddException e) {
            logger.warn("VM " + vmName + " violate name convention");
            return true;
        }
    }

    // if includeVolumes is true, this method must be called inside a transaction
    public NodeRead toNodeRead(boolean includeVolumes) {
        NodeRead node = new NodeRead();
        node.setRack(this.rack);
        node.setHostName(this.hostName);
        // For class NodeRead, keep "ipConfigsInfo" structure since it's used by software provision
        node.setIpConfigs(convertToIpConfigInfo());
        node.setName(this.vmName);
        node.setMoId(this.moId);
        node.setStatus(this.status != null ? this.status.toString() : null);
        node.setAction(this.action);
        node.setVersion(this.version);
        if (this.cpuNum != null) {
            node.setCpuNumber(this.cpuNum);
        }
        if (this.memorySize != null) {
            node.setMemory(this.memorySize);
        }
        List<String> roleNames = nodeGroup.getRoleNameList();
        node.setRoles(roleNames);
        if (includeVolumes)
            node.setVolumes(this.getVolumns());
        if (actionFailed) {
            node.setActionFailed(true);
        }
        if (errMessage != null && !errMessage.isEmpty()) {
            node.setErrMessage(errMessage);
        }
        return node;
    }

    /**
     * convert "nics" to NodeRead's "ipConfigInfo" field
     *
     * @return
     */
    public Map<NetTrafficType, List<IpConfigInfo>> convertToIpConfigInfo() {
        Map<NetTrafficType, List<IpConfigInfo>> ipConfigInfo = new HashMap<NetTrafficType, List<IpConfigInfo>>();
        if (nics != null) {
            for (NicEntity nicEntity : nics) {
                for (NicSpec.NetTrafficDefinition netDef : nicEntity.getNetTrafficDefs()) {
                    if (!ipConfigInfo.containsKey(netDef.getTrafficType())) {
                        ipConfigInfo.put(netDef.getTrafficType(), new ArrayList<IpConfigInfo>());
                    }
                    List<IpConfigInfo> ipInfo = ipConfigInfo.get(netDef.getTrafficType());
                    IpConfigInfo newIpConfig = new IpConfigInfo(netDef.getTrafficType(),
                            nicEntity.getNetworkEntity().getName(), nicEntity.getNetworkEntity().getPortGroup(),
                            nicEntity.getIpv4Address(), nicEntity.getFqdn());
                    if (netDef.getIndex() + 1 > ipInfo.size()) {
                        while (ipInfo.size() < netDef.getIndex() + 1) {
                            ipInfo.add(null);
                        }
                    }
                    ipInfo.remove(netDef.getIndex());
                    ipInfo.add(netDef.getIndex(), newIpConfig);
                }
            }
        }
        return ipConfigInfo;
    }

    @Override
    public int hashCode() {
        if (this.vmName != null) {
            return this.vmName.hashCode();
        }
        if (this.id != null) {
            return this.id.intValue();
        }
        return 0;
    }

    @Override
    public boolean equals(Object node) {
        if (!(node instanceof NodeEntity))
            return false;
        if (this.vmName != null && ((NodeEntity) node).getVmName() != null) {
            return ((NodeEntity) node).getVmName().equals(this.vmName);
        }
        return false;
    }

    public void cleanupErrorMessage() {
        this.actionFailed = false;
        this.errMessage = null;
        this.action = null;
    }

    public Set<NicEntity> getNics() {
        return nics;
    }

    public void setNics(Set<NicEntity> nics) {
        this.nics = nics;
    }

    public boolean isActionFailed() {
        return actionFailed;
    }

    public void setActionFailed(boolean actionFailed) {
        this.actionFailed = actionFailed;
    }

    public String getErrMessage() {
        return errMessage;
    }

    public void setErrMessage(String errMessage) {
        this.errMessage = errMessage;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public boolean needUpgrade(String serverVersion) {
        return (this.getMoId() != null && (this.getVersion() == null || !serverVersion.equals(this.getVersion())));
    }

    public boolean canBeUpgrade() {
        String nodeIp = this.getPrimaryMgtIpV4();
        return this.status.ordinal() >= NodeStatus.POWERED_ON.ordinal() && nodeIp != null
                && !Constants.NULL_IPV4_ADDRESS.equals(nodeIp);
    }

    public void cleanupErrorMessageForUpgrade() {
        this.actionFailed = false;
        this.errMessage = null;
        if (!canBeUpgrade()) {
            this.action = null;
        }
    }

    public boolean isVmReady() {
        return NodeStatus.VM_READY.equals(this.status);
    }

    public String getVmNameWithIP() {
        return this.getVmName() + "(" + this.getPrimaryMgtIpV4() + ")";
    }

    public boolean isNotExist() {
        return NodeStatus.NOT_EXIST.equals(this.status);
    }
}