diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index 730b85415d8..28b631c633b 100644 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -161,7 +161,7 @@ public interface ResponseGenerator { RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn); void createTemplateResponse(List responses, Pair templateZonePair, boolean isAdmin, - Account account); + Account account, boolean readyOnly); ListResponse createTemplateResponse2(VirtualMachineTemplate template, Long zoneId); @@ -187,7 +187,7 @@ public interface ResponseGenerator { EventResponse createEventResponse(Event event); - ListResponse createIsoResponse(Set> isoZonePairSet, boolean onlyReady, Account account, Boolean isBootable); + ListResponse createIsoResponse(Set> isoZonePairSet, boolean onlyReady, Account account, Boolean isBootable, boolean readyOnly); TemplateResponse createIsoResponse(VirtualMachineTemplate result); diff --git a/api/src/com/cloud/api/commands/ListIsosCmd.java b/api/src/com/cloud/api/commands/ListIsosCmd.java index 7d76b6989a9..c2765008620 100755 --- a/api/src/com/cloud/api/commands/ListIsosCmd.java +++ b/api/src/com/cloud/api/commands/ListIsosCmd.java @@ -124,6 +124,17 @@ public class ListIsosCmd extends BaseListCmd { public Long getZoneId() { return zoneId; } + + public boolean listInReadyState() { + Account account = UserContext.current().getCaller(); + // It is account specific if account is admin type and domainId and accountName are not null + boolean isAccountSpecific = (account == null || isAdmin(account.getType())) && (getAccountName() != null) && (getDomainId() != null); + // Show only those that are downloaded. + TemplateFilter templateFilter = TemplateFilter.valueOf(getIsoFilter()); + boolean onlyReady = (templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.selfexecutable) || (templateFilter == TemplateFilter.sharedexecutable) + || (templateFilter == TemplateFilter.executable && isAccountSpecific) || (templateFilter == TemplateFilter.community); + return onlyReady; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// @@ -160,7 +171,7 @@ public class ListIsosCmd extends BaseListCmd { isAdmin = true; } - ListResponse response = _responseGenerator.createIsoResponse(isoZonePairSet, isAdmin, account, bootable); + ListResponse response = _responseGenerator.createIsoResponse(isoZonePairSet, isAdmin, account, bootable, listInReadyState()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListTemplatesCmd.java b/api/src/com/cloud/api/commands/ListTemplatesCmd.java index ae88c63fce5..6f58acd829f 100755 --- a/api/src/com/cloud/api/commands/ListTemplatesCmd.java +++ b/api/src/com/cloud/api/commands/ListTemplatesCmd.java @@ -105,6 +105,17 @@ public class ListTemplatesCmd extends BaseListCmd { public Long getZoneId() { return zoneId; } + + public boolean listInReadyState() { + Account account = UserContext.current().getCaller(); + // It is account specific if account is admin type and domainId and accountName are not null + boolean isAccountSpecific = (account == null || isAdmin(account.getType())) && (getAccountName() != null) && (getDomainId() != null); + // Show only those that are downloaded. + TemplateFilter templateFilter = TemplateFilter.valueOf(getTemplateFilter()); + boolean onlyReady = (templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.selfexecutable) || (templateFilter == TemplateFilter.sharedexecutable) + || (templateFilter == TemplateFilter.executable && isAccountSpecific) || (templateFilter == TemplateFilter.community); + return onlyReady; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// @@ -133,7 +144,7 @@ public class ListTemplatesCmd extends BaseListCmd { List templateResponses = new ArrayList(); for (Pair template : templateZonePairSet) { - _responseGenerator.createTemplateResponse(templateResponses, template, isAdmin, account); + _responseGenerator.createTemplateResponse(templateResponses, template, isAdmin, account, listInReadyState()); } response.setResponses(templateResponses); diff --git a/api/src/com/cloud/api/response/TemplateResponse.java b/api/src/com/cloud/api/response/TemplateResponse.java index 696848a4efa..2c97f64cabd 100755 --- a/api/src/com/cloud/api/response/TemplateResponse.java +++ b/api/src/com/cloud/api/response/TemplateResponse.java @@ -19,6 +19,7 @@ package com.cloud.api.response; import java.util.Date; +import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; import com.cloud.storage.Storage.ImageFormat; import com.google.gson.annotations.SerializedName; @@ -113,6 +114,12 @@ public class TemplateResponse extends BaseResponse { @SerializedName("sourcetemplateid") @Param(description="the template ID of the parent template if present") private Long sourcetemplateId; + @SerializedName(ApiConstants.HOST_ID) @Param(description="the ID of the secondary storage host for the template") + private Long hostId; + + @SerializedName("hostname") @Param(description="the name of the secondary storage host for the template") + private String hostName; + public Long getObjectId() { return getId(); } @@ -348,4 +355,20 @@ public class TemplateResponse extends BaseResponse { public void setSourceTemplateId(Long sourcetemplateId) { this.sourcetemplateId = sourcetemplateId; } + + public Long getHostId() { + return hostId; + } + + public void setHostId(Long hostId) { + this.hostId = hostId; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 433b7ca0886..bded506edee 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -478,20 +478,13 @@ public class ApiDBUtils { return _volumeDao.getHypervisorType(volumeId); } - public static List listTemplateHostBy(long templateId, Long zoneId) { + public static List listTemplateHostBy(long templateId, Long zoneId, boolean readyOnly) { if (zoneId != null) { VMTemplateVO vmTemplate = findTemplateById(templateId); if (vmTemplate.getHypervisorType() == HypervisorType.BareMetal) { return _templateHostDao.listByTemplateId(templateId); } else { - List templates = new ArrayList(); - List secondaryStorageHosts = _storageMgr.getSecondaryStorageHosts(zoneId); - if (!secondaryStorageHosts.isEmpty()) { - for (HostVO ssh : secondaryStorageHosts) { - templates.addAll(_templateHostDao.listByHostTemplate(ssh.getId(), templateId)); - } - } - return templates; + return _templateHostDao.listByZoneTemplate(zoneId, templateId, readyOnly); } } else { return _templateHostDao.listByOnlyTemplateId(templateId); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 53a2a663fc3..691492d5080 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1449,12 +1449,21 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public void createTemplateResponse(List responses, Pair templateZonePair, boolean isAdmin, Account account) { - List templateHostRefsForTemplate = ApiDBUtils.listTemplateHostBy(templateZonePair.first(), templateZonePair.second()); + public void createTemplateResponse(List responses, Pair templateZonePair, boolean isAdmin, Account account, boolean readyOnly) { + List templateHostRefsForTemplate = ApiDBUtils.listTemplateHostBy(templateZonePair.first(), templateZonePair.second(), readyOnly); VMTemplateVO template = ApiDBUtils.findTemplateById(templateZonePair.first()); for (VMTemplateHostVO templateHostRef : templateHostRefsForTemplate) { - + if (readyOnly) { + if (templateHostRef.getDownloadState() != Status.DOWNLOADED) { + continue; + } + for (TemplateResponse res : responses) { + if (res.getId() == templateHostRef.getTemplateId()) { + continue; + } + } + } TemplateResponse templateResponse = new TemplateResponse(); templateResponse.setId(template.getId()); templateResponse.setName(template.getName()); @@ -1491,8 +1500,11 @@ public class ApiResponseHelper implements ResponseGenerator { } HostVO host = ApiDBUtils.findHostById(templateHostRef.getHostId()); + templateResponse.setHostId(host.getId()); + templateResponse.setHostName(host.getName()); + DataCenterVO datacenter = ApiDBUtils.findZoneById(host.getDataCenterId()); - + // Add the zone ID templateResponse.setZoneId(host.getDataCenterId()); templateResponse.setZoneName(datacenter.getName()); @@ -1986,7 +1998,7 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public ListResponse createIsoResponse(Set> isoZonePairSet, boolean isAdmin, Account account, Boolean isBootable) { + public ListResponse createIsoResponse(Set> isoZonePairSet, boolean isAdmin, Account account, Boolean isBootable, boolean readyOnly) { ListResponse response = new ListResponse(); List isoResponses = new ArrayList(); @@ -2022,7 +2034,7 @@ public class ApiResponseHelper implements ResponseGenerator { } } - List isoHosts = ApiDBUtils.listTemplateHostBy(iso.getId(), isoZonePair.second()); + List isoHosts = ApiDBUtils.listTemplateHostBy(iso.getId(), isoZonePair.second(), readyOnly); for (VMTemplateHostVO isoHost : isoHosts) { TemplateResponse isoResponse = new TemplateResponse(); isoResponse.setId(iso.getId()); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 48967532843..d9d291e7858 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1624,7 +1624,7 @@ public class ManagementServerImpl implements ManagementServer { HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return listTemplates(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), accountId, cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, - isAccountSpecific, true); + isAccountSpecific, true, cmd.listInReadyState()); } @Override @@ -1646,11 +1646,11 @@ public class ManagementServerImpl implements ManagementServer { HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return listTemplates(cmd.getId(), cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, accountId, cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, - isAccountSpecific, showDomr); + isAccountSpecific, showDomr, cmd.listInReadyState()); } private Set> listTemplates(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long accountId, Long pageSize, - Long startIndex, Long zoneId, HypervisorType hyperType, boolean isAccountSpecific, boolean showDomr) { + Long startIndex, Long zoneId, HypervisorType hyperType, boolean isAccountSpecific, boolean showDomr, boolean onlyReady) { Account caller = UserContext.current().getCaller(); VMTemplateVO template = null; @@ -1669,10 +1669,6 @@ public class ManagementServerImpl implements ManagementServer { } } - // Show only those that are downloaded. - boolean onlyReady = (templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.selfexecutable) || (templateFilter == TemplateFilter.sharedexecutable) - || (templateFilter == TemplateFilter.executable && isAccountSpecific) || (templateFilter == TemplateFilter.community); - Account account = null; DomainVO domain = null; if (accountId != null) { diff --git a/server/src/com/cloud/storage/dao/VMTemplateHostDao.java b/server/src/com/cloud/storage/dao/VMTemplateHostDao.java index fef0217e878..d03ac1322b8 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateHostDao.java +++ b/server/src/com/cloud/storage/dao/VMTemplateHostDao.java @@ -56,7 +56,7 @@ public interface VMTemplateHostDao extends GenericDao { boolean templateAvailable(long templateId, long hostId); - List listByZoneTemplate(long dcId, long templateId); + List listByZoneTemplate(long dcId, long templateId, boolean readyOnly); void deleteByHost(Long hostId); diff --git a/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java index 8d605a8e29e..15021f7f0fb 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java @@ -24,15 +24,22 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.TimeZone; import javax.ejb.Local; +import javax.naming.ConfigurationException; import org.apache.log4j.Logger; + +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.DateUtil; +import com.cloud.utils.component.Inject; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @@ -40,7 +47,8 @@ import com.cloud.utils.db.Transaction; @Local(value={VMTemplateHostDao.class}) public class VMTemplateHostDaoImpl extends GenericDaoBase implements VMTemplateHostDao { public static final Logger s_logger = Logger.getLogger(VMTemplateHostDaoImpl.class.getName()); - + @Inject + HostDao _hostDao; protected final SearchBuilder HostSearch; protected final SearchBuilder TemplateSearch; protected final SearchBuilder HostTemplateSearch; @@ -49,6 +57,7 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase HostTemplatePoolSearch; protected final SearchBuilder TemplateStatusSearch; protected final SearchBuilder TemplateStatesSearch; + protected SearchBuilder ZONE_TEMPLATE_SEARCH; protected static final String UPDATE_TEMPLATE_HOST_REF = @@ -71,12 +80,6 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase params) throws ConfigurationException { + boolean result = super.configure(name, params); + ZONE_TEMPLATE_SEARCH = createSearchBuilder(); + ZONE_TEMPLATE_SEARCH.and("template_id", ZONE_TEMPLATE_SEARCH.entity().getTemplateId(), SearchCriteria.Op.EQ); + ZONE_TEMPLATE_SEARCH.and("state", ZONE_TEMPLATE_SEARCH.entity().getDownloadState(), SearchCriteria.Op.EQ); + SearchBuilder hostSearch = _hostDao.createSearchBuilder(); + hostSearch.and("zone_id", hostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + ZONE_TEMPLATE_SEARCH.join("tmplHost", hostSearch, hostSearch.entity().getId(), ZONE_TEMPLATE_SEARCH.entity().getHostId(), JoinBuilder.JoinType.INNER); + ZONE_TEMPLATE_SEARCH.done(); + return result; } - @Override public void update(VMTemplateHostVO instance) { Transaction txn = Transaction.currentTxn(); @@ -275,25 +290,18 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase listByZoneTemplate(long dcId, long templateId) { - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - try { - String sql = ZONE_TEMPLATE_SEARCH; - pstmt = txn.prepareStatement(sql); - - pstmt.setLong(1, dcId); - pstmt.setLong(2, templateId); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - result.add(toEntityBean(rs, false)); - } - - } catch (Exception e) { - s_logger.warn("Exception: ", e); + public List listByZoneTemplate(long dcId, long templateId, boolean readyOnly) { + SearchCriteria sc = ZONE_TEMPLATE_SEARCH.create(); + sc.setParameters("template_id", templateId); + sc.setJoinParameters("tmplHost", "zone_id", dcId); + if (readyOnly) { + sc.setParameters("state", VMTemplateHostVO.Status.DOWNLOADED); + List tmplHost = new ArrayList(); + tmplHost.add(findOneBy(sc)); + return tmplHost; + } else { + return listBy(sc); } - return result; } @Override diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 1a309f2cb67..a492396ff1b 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -535,7 +535,7 @@ public class DownloadMonitorImpl implements DownloadMonitor { if( tmplt.isPublicTemplate() || tmplt.isFeatured() ) { continue; } - List tmpltHosts = _vmTemplateHostDao.listByZoneTemplate(dcId, tmplt.getId()); + List tmpltHosts = _vmTemplateHostDao.listByZoneTemplate(dcId, tmplt.getId(), false); for ( VMTemplateHostVO tmpltHost : tmpltHosts ) { if ( tmpltHost.getDownloadState() == Status.DOWNLOADED || tmpltHost.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) { iter.remove();