/** * 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.api.services.appslibrary.event; import java.math.BigInteger; import java.util.LinkedList; import java.util.List; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.abiquo.api.services.DatacenterService; import com.abiquo.api.tracer.TracerLogger; import com.abiquo.appliancemanager.transport.TemplateDto; import com.abiquo.model.enumerator.DiskFormatType; import com.abiquo.server.core.appslibrary.AppsLibraryRep; import com.abiquo.server.core.appslibrary.Category; import com.abiquo.server.core.appslibrary.TemplateDefinition; import com.abiquo.server.core.appslibrary.TemplateDefinitionDAO; import com.abiquo.server.core.appslibrary.VirtualMachineTemplate; import com.abiquo.server.core.enterprise.Enterprise; import com.abiquo.server.core.enterprise.EnterpriseRep; import com.abiquo.server.core.infrastructure.Datacenter; import com.abiquo.server.core.infrastructure.Repository; import com.abiquo.tracer.User; /** * Transforms an {@link TemplateDto} from ApplianceManager into a {@link VirtualMachineTemplate} in * API */ @Service public class TemplateFactory { protected final static Logger logger = LoggerFactory.getLogger(TemplateFactory.class); @Autowired private AppsLibraryRep appslibraryRep; @Autowired private TemplateDefinitionDAO templateDefDao; @Autowired private EnterpriseRep entRepo; @Autowired protected DatacenterService dcService; @Autowired protected TracerLogger tracer; @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public List<VirtualMachineTemplate> insertVirtualMachineTemplates( final List<TemplateDto> disks, final Repository repo) { List<VirtualMachineTemplate> addedvmtemplates = new LinkedList<VirtualMachineTemplate>(); List<TemplateDto> disksToInsert = filterAlreadyInsertedVirtualMachineTemplatePathsOrEnterpriseDoNotExist(disks, repo); // first masters for (TemplateDto disk : disksToInsert) { if (disk.getMasterDiskFilePath() == null) { try { VirtualMachineTemplate vi = virtualMachineTemplateFromTemplate(disk, repo); appslibraryRep.insertVirtualMachineTemplate(vi); addedvmtemplates.add(vi); logger.info("Inserted virtual machine template [{}]", vi.getPath()); } catch (Exception pe) { logger.error("Can not insert virtual machine template [{}]", disk.getDiskFilePath()); } } } // second bunded for (TemplateDto disk : disksToInsert) { if (disk.getMasterDiskFilePath() != null) { try { VirtualMachineTemplate vi = virtualMachineTemplateFromTemplate(disk, repo); appslibraryRep.insertVirtualMachineTemplate(vi); addedvmtemplates.add(vi); logger.info("Inserted bundle virtual machine template [{}]", vi.getPath()); } catch (Exception pe) { logger.error("Can not insert bundle virtual machine template [{}]", disk.getDiskFilePath()); } } } return addedvmtemplates; } /** * Filer already present virtual machne template paths. Ignore virtual vmtemplates from not * present enterprise repository. */ private List<TemplateDto> filterAlreadyInsertedVirtualMachineTemplatePathsOrEnterpriseDoNotExist( final List<TemplateDto> disks, final Repository repository) { List<TemplateDto> notInsertedDisks = new LinkedList<TemplateDto>(); for (TemplateDto disk : disks) { Enterprise enterprise = entRepo.findById(disk.getEnterpriseRepositoryId()); if (enterprise != null) { if (!appslibraryRep.existVirtualMachineTemplateWithSamePath(enterprise, repository, disk.getDiskFilePath())) { notInsertedDisks.add(disk); } } } return notInsertedDisks; } @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public void generateConversions(final List<VirtualMachineTemplate> templates, final Datacenter datacenter) { // community do nothing } @Transactional(readOnly = false, propagation = Propagation.REQUIRED) protected VirtualMachineTemplate virtualMachineTemplateFromTemplate(final TemplateDto disk, final Repository repository) { Enterprise enterprise = entRepo.findById(disk.getEnterpriseRepositoryId()); DiskFormatType diskFormat; VirtualMachineTemplate master = null; if (disk.getMasterDiskFilePath() != null) { master = appslibraryRep.findVirtualMachineTemplateByPath(enterprise, repository, disk.getDiskFilePath()); diskFormat = master.getDiskFormatType(); } else { diskFormat = DiskFormatType.valueOf(disk.getDiskFileFormat().name().toUpperCase()); } Category category = getCategory(disk); VirtualMachineTemplate vmtemplate = new VirtualMachineTemplate(enterprise, disk.getName(), diskFormat, disk.getDiskFilePath(), disk.getDiskFileSize(), category, User.SYSTEM_USER.getName()); // TODO vmtemplate.setIconUrl(getIcon(disk)); vmtemplate.setDescription(getDescription(disk)); vmtemplate.setCpuRequired(disk.getCpu()); vmtemplate.setRamRequired(getRamInMb(disk).intValue()); vmtemplate.setHdRequiredInBytes(getHdInBytes(disk)); vmtemplate.setOvfid(disk.getUrl()); vmtemplate.setRepository(repository); if (disk.getEthernetDriverType() != null) { vmtemplate.setEthernetDriverType(disk.getEthernetDriverType()); } if (master != null) { vmtemplate.setMaster(master); } return vmtemplate; } /** * If the icon is not found in the OVF document then look in the {@link TemplateDefinition} * table (from the ovfindex.xml) */ private String getIcon(final TemplateDto template) { if (!StringUtils.isEmpty(template.getIconPath())) { return template.getIconPath(); } TemplateDefinition tdef = templateDefDao.findByUrl(template.getUrl()); if (tdef != null) { logger.warn("Missing icon url in the OVF document, reading from ovfindex"); return tdef.getIconUrl(); } return null; } private Category getCategory(final TemplateDto disk) { String categoryName = disk.getCategoryName(); if (!StringUtils.isEmpty(categoryName)) { return appslibraryRep.findByCategoryNameOrCreateNew(disk.getCategoryName()); } // try to find in the TemplateDefinition TemplateDefinition templateDef = templateDefDao.findByUrl(disk.getUrl()); return templateDef != null ? templateDef.getCategory() : appslibraryRep .getDefaultCategory(); } /* * returns a 254 trucated description. TODO in the DAO */ private String getDescription(final TemplateDto disk) { String truncatedDescription = disk.getDescription(); if (truncatedDescription.length() > 254) // TODO data truncation { truncatedDescription = truncatedDescription.substring(0, 254); } return truncatedDescription; } private Long getRamInMb(final TemplateDto disk) { BigInteger byteRam = getBytes(String.valueOf(disk.getRam()), disk.getRamSizeUnit().name()); return byteRam.longValue() / 1048576; } private Long getHdInBytes(final TemplateDto disk) { return getBytes(String.valueOf(disk.getHd()), disk.getHdSizeUnit().name()).longValue(); } /** * Gets the disk capacity on bytes. * * @param capacity, numeric value * @param alloctionUnit, bytes by default but can be Kb, Mb, Gb or Tb. * @return capacity on bytes **/ private static BigInteger getBytes(final String capacity, final String allocationUnits) { BigInteger capa = new BigInteger(capacity); if (allocationUnits == null) { return capa; } if ("byte".equalsIgnoreCase(allocationUnits) || "bytes".equalsIgnoreCase(allocationUnits)) { return capa; } BigInteger factor = new BigInteger("2"); if ("byte * 2^10".equals(allocationUnits) || "KB".equalsIgnoreCase(allocationUnits) || "KILOBYTE".equalsIgnoreCase(allocationUnits) || "KILOBYTES".equalsIgnoreCase(allocationUnits)) // kb { factor = factor.pow(10); } else if ("byte * 2^20".equals(allocationUnits) || "MB".equalsIgnoreCase(allocationUnits) || "MEGABYTE".equalsIgnoreCase(allocationUnits) || "MEGABYTES".equalsIgnoreCase(allocationUnits)) // mb { factor = factor.pow(20); } else if ("byte * 2^30".equals(allocationUnits) || "GB".equalsIgnoreCase(allocationUnits) || "GIGABYTE".equalsIgnoreCase(allocationUnits) || "GIGABYTES".equalsIgnoreCase(allocationUnits)) // gb { factor = factor.pow(30); } else if ("byte * 2^40".equals(allocationUnits) || "TB".equalsIgnoreCase(allocationUnits) || "TERABYTE".equalsIgnoreCase(allocationUnits) || "TERABYTES".equalsIgnoreCase(allocationUnits)) // tb { factor = factor.pow(40); } else { final String msg = "Unknow disk capacityAllocationUnits factor [" + allocationUnits + "]"; throw new RuntimeException(msg); } return capa.multiply(factor); } }