package org.hyperic.hq.vm;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.NonUniqueResultException;
import org.hibernate.SessionFactory;
import org.hyperic.hq.dao.HibernateDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.hyperic.hq.vm.VmMapping;
@Repository
public class VCDAO extends HibernateDAO<VmMapping> {
protected final Log log = LogFactory.getLog(VCDAO.class.getName());
@Autowired
protected VCDAO(SessionFactory f) {
super(VmMapping.class, f);
}
public void remove(List<VmMapping> macToUUIDs) {
for(VmMapping macToUUID:macToUUIDs) {
this.remove(macToUUID);
}
getSession().flush();
}
/**
* This method calls to HibernateDAO save method that uses Hibernate saveOrUpdate method.
* In case of an update the method set the Hibernate DB object properties
*
* @param macToUUIDs List of VMs to save or update
*
*/
public void save(List<VmMapping> macToUUIDs) {
VmMapping dbVmMap = null;
for(VmMapping macToUUID:macToUUIDs) {
try {
dbVmMap = findVMByMoref(macToUUID.getVcUUID(), macToUUID.getMoId());
} catch (NonUniqueResultException e) {
log.warn("Found duplicate VM's MOREF entires in DB. Ignore from VM [" + macToUUID + "]", e);
continue;
}
// Check if this is a new VM
if (null == dbVmMap){
// Verify that the MAC Address is unique
try {
dbVmMap = findVMByMac(macToUUID.getMacs());
if (null == dbVmMap){
dbVmMap = macToUUID;
// mac exists with different MOREF fields (different VM)
} else{
log.warn("The mac is already exist in VM [" + dbVmMap + "]\nIgnore from [" + macToUUID + "]");
continue;
}
} catch (DupMacException e) {
log.warn("Found duplicate MAC address.Ignore from VM [" + macToUUID + "]", e);
continue;
}
}else {
if (log.isDebugEnabled()){
log.debug("Update existing VM instance properties [" + dbVmMap + "]");
}
// Update the VM instance properties
dbVmMap.set_version_(macToUUID.get_version_());
dbVmMap.setName(macToUUID.getName());
dbVmMap.setGuestNicInfo(macToUUID.getGuestNicInfo());
dbVmMap.setMacs(macToUUID.getMacs());
}
if (log.isDebugEnabled()){
log.debug("Save VM [" + dbVmMap + "]");
}
super.save(dbVmMap);
}
getSession().flush();
}
@SuppressWarnings("unchecked")
public List<VmMapping> findByVcUUID(String vcUUID) {
String sql = "from VmMapping u where u.vcUUID = :vcUUID";
return (List<VmMapping>) getSession().createQuery(sql).setString("vcUUID", vcUUID).list();
}
@SuppressWarnings("unchecked")
public List<VmMapping> getVMsFromOtherVcenters(String vcUUID) {
String sql = "from VmMapping u where u.vcUUID <> :vcUUID";
return (List<VmMapping>) getSession().createQuery(sql).setString("vcUUID", vcUUID).list();
}
@SuppressWarnings("unchecked")
public VMID findByMac(String mac) throws DupMacException {
String sql = "from VmMapping u where u.macs like '%+mac+%'";
sql = sql.replace("+mac+", mac);
List<VmMapping> rs = getSession().createQuery(sql).list();
if (rs.size()==0) {
if (log.isDebugEnabled()){
log.debug("findByMac: no IDs are recorded for " + mac);
}
return null;
}
if (rs.size()>1) {
throw new DupMacException("duplicate mac address " + mac + " in the VmMapping table");
}
VmMapping macToUUID = rs.iterator().next();
return new VMID(macToUUID.getMoId(),macToUUID.getVcUUID());
}
@SuppressWarnings("unchecked")
public VmMapping findVMByMac(String mac) throws DupMacException {
String sql = "from VmMapping u where u.macs like '%+mac+%'";
sql = sql.replace("+mac+", mac);
List<VmMapping> rs = getSession().createQuery(sql).list();
if (rs.size()==0) {
if (log.isDebugEnabled()){
log.debug("findVMByMac: no IDs are recorded for " + mac);
}
return null;
}
if (rs.size()>1) {
throw new DupMacException("duplicate mac address " + mac + " in the VmMapping table");
}
VmMapping macToUUID = rs.iterator().next();
return macToUUID;
}
/**
* Find a VM in EAM_VM_MAPPING table by vcUUID and moId
*
* @param vcUUID
* @param moId
* @return
* @throws DupMacException
*/
public VmMapping findVMByMoref(String vcUUID, String moId) throws NonUniqueResultException {
String sql = "from VmMapping u where u.vcUUID = :vcUUID and u.moId = :moId";
return (VmMapping) getSession().createQuery(sql).setString("vcUUID", vcUUID).setString("moId", moId).uniqueResult();
}
}