/**
* 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;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Hibernate;
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.exceptions.APIError;
import com.abiquo.api.services.DefaultApiService;
import com.abiquo.api.services.EnterpriseService;
import com.abiquo.api.services.stub.AMServiceStub;
import com.abiquo.api.tracer.TracerLogger;
import com.abiquo.appliancemanager.repositoryspace.OVFDescription;
import com.abiquo.appliancemanager.repositoryspace.RepositorySpace;
import com.abiquo.appliancemanager.transport.TemplatesStateDto;
import com.abiquo.model.transport.error.CommonError;
import com.abiquo.ovfmanager.ovf.exceptions.XMLException;
import com.abiquo.server.core.appslibrary.AppsLibrary;
import com.abiquo.server.core.appslibrary.AppsLibraryDAO;
import com.abiquo.server.core.appslibrary.TemplateDefinition;
import com.abiquo.server.core.appslibrary.TemplateDefinitionList;
import com.abiquo.server.core.appslibrary.TemplateDefinitionRep;
import com.abiquo.server.core.enterprise.Enterprise;
import com.abiquo.tracer.ComponentType;
import com.abiquo.tracer.EventType;
import com.abiquo.tracer.SeverityType;
@Service
public class TemplateDefinitionListService extends DefaultApiService
{
private final static Logger LOGGER = LoggerFactory
.getLogger(TemplateDefinitionListService.class);
@Autowired
protected AppsLibraryDAO appsLibraryDao;
@Autowired
protected TemplateDefinitionRep repo;
@Autowired
protected TemplateDefinitionService templateDefinitionService;
@Autowired
private EnterpriseService enterpriseService;
@Autowired
private AMServiceStub amService;
@Autowired
protected TracerLogger tracer;
public TemplateDefinitionListService()
{
}
public TemplateDefinitionListService(final EntityManager em)
{
repo = new TemplateDefinitionRep(em);
enterpriseService = new EnterpriseService(em);
appsLibraryDao = new AppsLibraryDAO(em);
templateDefinitionService = new TemplateDefinitionService(em);
tracer = new TracerLogger();
amService = new AMServiceStub();
}
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public List<TemplateDefinitionList> getOVFPackageLists()
{
return repo.getTemplateDefinitionLists();
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public TemplateDefinitionList addTemplateDefinitionList(
final TemplateDefinitionList templateDefList, final Integer idEnterprise)
{
final String name = templateDefList.getName();
Enterprise ent = enterpriseService.getEnterprise(idEnterprise);
AppsLibrary appsLib = appsLibraryDao.findByEnterpriseOrInitialize(ent);
templateDefList.setAppsLibrary(appsLib);
validate(templateDefList);
for (TemplateDefinition templateDef : templateDefList.getTemplateDefinitions())
{
templateDef.setAppsLibrary(appsLib);
// validate(templateDef);
}
TemplateDefinitionList prevlist = null;
prevlist = repo.findTemplateDefinitionListByNameAndEnterprise(name, ent);
if (prevlist != null)
{
addConflictErrors(APIError.TEMPLATE_DEFINITION_LIST_NAME_ALREADY_EXIST);
flushErrors();
}
repo.persistTemplateDefinitionList(templateDefList);
for (TemplateDefinition templateDef : templateDefList.getTemplateDefinitions())
{
if (templateDef.isValid())
{// TemplateDefinition tDef =
templateDefinitionService.addTemplateDefinition(templateDef, idEnterprise);
templateDef.addToTemplateDefinitionLists(templateDefList);
}
else
{
templateDef.getTemplateDefinitionLists().clear();
if (tracer != null)
{
tracer.log(SeverityType.WARNING, ComponentType.APPLIANCE_MANAGER,
EventType.TEMPLATE_DEFINITION_LIST_MODIFIED,
"templateDefinition.createError", templateDef.getName(),
validationErrors(templateDef.getValidationErrors()));
}
}
}
// templateDefList.setTemplateDefinitions(correctTemplates);
repo.updateTemplateDefinitionList(templateDefList);
return templateDefList;
}
private String validationErrors(final Set<CommonError> errors)
{
StringBuilder sbuilder = new StringBuilder();
for (CommonError error : errors)
{
sbuilder.append(String.format("%s - %s\n", error.getCode(), error.getMessage()));
}
return sbuilder.toString();
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public TemplateDefinitionList addTemplateDefinitionList(final String ovfindexURL,
final Integer idEnterprise)
{
TemplateDefinitionList ovfPackageList =
obtainTemplateDefinitionListFromOVFIndexUrl(ovfindexURL);
return addTemplateDefinitionList(ovfPackageList, idEnterprise);
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public TemplateDefinitionList getTemplateDefinitionList(final Integer id,
final Integer idEnterprise)
{
enterpriseService.getEnterprise(idEnterprise); // check can view
TemplateDefinitionList templateDefinitionList = repo.getTemplateDefinitionList(id);
if (templateDefinitionList == null)
{
addNotFoundErrors(APIError.NON_EXISTENT_TEMPLATE_DEFINITION_LIST);
flushErrors();
}
Hibernate.initialize(templateDefinitionList.getTemplateDefinitions());
return templateDefinitionList;
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public TemplatesStateDto getTemplateListStatus(final Integer id, final Integer datacenterId,
final Integer enterpriseId)
{
final TemplateDefinitionList templateDefinitionList =
getTemplateDefinitionList(id, enterpriseId);
return amService.getTemplatesState(datacenterId, enterpriseId,
getListIds(templateDefinitionList));
}
private String[] getListIds(final TemplateDefinitionList list)
{
ArrayList<String> ids = new ArrayList<String>();
for (TemplateDefinition tdef : list.getTemplateDefinitions())
{
ids.add(tdef.getUrl());
}
return ids.toArray(new String[ids.size()]);
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public TemplateDefinitionList refreshTemplateDefinitionList(final Integer idEnterprise,
final Integer idList)
{
enterpriseService.getEnterprise(idEnterprise); // check can view
TemplateDefinitionList oldList = repo.getTemplateDefinitionList(idList);
if (oldList == null)
{
addNotFoundErrors(APIError.NON_EXISTENT_TEMPLATE_DEFINITION_LIST);
flushErrors();
}
final String listUrl = oldList.getUrl();
if (StringUtils.isEmpty(listUrl))
{
addConflictErrors(APIError.TEMPLATE_DEFINITION_LIST_REFRESH_NO_URL);
flushErrors();
}
TemplateDefinitionList newList = obtainTemplateDefinitionListFromOVFIndexUrl(listUrl);
removeTemplateDefinitionList(idList, true, idEnterprise);
return addTemplateDefinitionList(newList, idEnterprise);
}
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public List<TemplateDefinitionList> getTemplateDefinitionListsByEnterprise(
final Integer idEnterprise) throws SocketTimeoutException
{
enterpriseService.getEnterprise(idEnterprise);
List<TemplateDefinitionList> ovfPackageList = new ArrayList<TemplateDefinitionList>();
ovfPackageList = repo.getTemplateDefinitionListsByEnterprise(idEnterprise);
return ovfPackageList;
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public TemplateDefinitionList updateTemplateDefinitionList(final Integer templateDefListId,
final TemplateDefinitionList templateDefList, final Integer idEnterprise)
{
Enterprise ent = enterpriseService.getEnterprise(idEnterprise);
TemplateDefinitionList old = repo.getTemplateDefinitionList(templateDefListId);
if (old == null)
{
addNotFoundErrors(APIError.NON_EXISTENT_TEMPLATE_DEFINITION_LIST);
flushErrors();
}
old.setName(templateDefList.getName());
old.setTemplateDefinitions(templateDefList.getTemplateDefinitions());
AppsLibrary appsLib = appsLibraryDao.findByEnterprise(ent);
old.setAppsLibrary(appsLib);
validate(old);
for (TemplateDefinition templateDef : old.getTemplateDefinitions())
{
validate(templateDef);
}
repo.updateTemplateDefinitionList(old);
tracer.log(SeverityType.INFO, ComponentType.WORKLOAD,
EventType.TEMPLATE_DEFINITION_LIST_MODIFIED, "templateDefinitionList.updated",
templateDefList.getName());
return old;
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void removeTemplateDefinitionList(final Integer id, final boolean refresh,
final Integer idEnterprise)
{
enterpriseService.getEnterprise(idEnterprise);
TemplateDefinitionList templateDefList = repo.getTemplateDefinitionList(id);
if (templateDefList == null)
{
addNotFoundErrors(APIError.NON_EXISTENT_TEMPLATE_DEFINITION_LIST);
flushErrors();
}
if (!refresh)
{
tracer.log(SeverityType.INFO, ComponentType.WORKLOAD,
EventType.TEMPLATE_DEFINITION_LIST_DELETED, "templateDefinitionList.deleted",
templateDefList.getName());
}
repo.removeTemplateDefinitionList(templateDefList);
}
private TemplateDefinitionList obtainTemplateDefinitionListFromOVFIndexUrl(String ovfindexUrl)
{
if (!ovfindexUrl.endsWith("/ovfindex.xml"))
{
if (ovfindexUrl.endsWith("/"))
{
ovfindexUrl += "ovfindex.xml";
}
else
{
String suffix = ovfindexUrl.endsWith(".xml") ? "" : "/ovfindex.xml";
ovfindexUrl += suffix;
}
}
TemplateDefinitionList list = new TemplateDefinitionList();
RepositorySpace repo = null;
try
{
RepositorySpaceXML ovfindexXML = RepositorySpaceXML.getInstance();
repo = ovfindexXML.obtainRepositorySpace(ovfindexUrl);
}
catch (XMLException e)
{
final String cause =
String.format("Can not find the RepositorySpace at [%s]", ovfindexUrl);
LOGGER.debug(cause);
addValidationErrors(APIError.INVALID_OVF_INDEX_XML);
flushErrors();
}
catch (MalformedURLException e)
{
final String cause =
String.format("Invalid repository space identifier : [%s]", ovfindexUrl);
LOGGER.debug(cause);
addNotFoundErrors(APIError.NON_EXISTENT_REPOSITORY_SPACE);
flushErrors();
}
catch (IOException e)
{
final String cause = String.format("Can not open a connection to : [%s]", ovfindexUrl);
LOGGER.debug(cause);
addNotFoundErrors(APIError.NON_EXISTENT_REPOSITORY_SPACE);
flushErrors();
}
String baseRepositorySpaceURL = "";
if (ovfindexUrl.lastIndexOf('/') != -1)
{
baseRepositorySpaceURL = ovfindexUrl.substring(0, ovfindexUrl.lastIndexOf('/'));
}
for (OVFDescription description : repo.getOVFDescription())
{
TemplateDefinition pack =
templateDefinitionService.transformToTemplateDefinition(description,
baseRepositorySpaceURL);
list.getTemplateDefinitions().add(pack);
}
list.setName(repo.getRepositoryName());
list.setUrl(ovfindexUrl);
return list;
}
}