diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java index e6ffca06f9e0..4936af3caab5 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java @@ -162,4 +162,6 @@ public interface VolumeDao extends GenericDao, StateDao searchRemovedByVms(List vmIds, Long batchSize); VolumeVO findOneByIScsiName(String iScsiName); + + int getVolumeCountByOfferingId(long diskOfferingId); } diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java index 750dbf2bee0f..5ef64b046646 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java @@ -77,6 +77,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol protected GenericSearchBuilder primaryStorageSearch2; protected GenericSearchBuilder secondaryStorageSearch; private final SearchBuilder poolAndPathSearch; + final GenericSearchBuilder CountByOfferingId; @Inject ReservationDao reservationDao; @@ -504,6 +505,11 @@ public VolumeDaoImpl() { poolAndPathSearch.and("poolId", poolAndPathSearch.entity().getPoolId(), Op.EQ); poolAndPathSearch.and("path", poolAndPathSearch.entity().getPath(), Op.EQ); poolAndPathSearch.done(); + + CountByOfferingId = createSearchBuilder(Integer.class); + CountByOfferingId.select(null, Func.COUNT, CountByOfferingId.entity().getId()); + CountByOfferingId.and("diskOfferingId", CountByOfferingId.entity().getDiskOfferingId(), Op.EQ); + CountByOfferingId.done(); } @Override @@ -909,4 +915,12 @@ public VolumeVO findOneByIScsiName(String iScsiName) { sc.setParameters("iScsiName", iScsiName); return findOneIncludingRemovedBy(sc); } + + @Override + public int getVolumeCountByOfferingId(long diskOfferingId) { + SearchCriteria sc = CountByOfferingId.create(); + sc.setParameters("diskOfferingId", diskOfferingId); + List results = customSearch(sc, null); + return results.get(0); + } } diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDao.java index 823642d8c3d7..dde22d431edf 100755 --- a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDao.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDao.java @@ -187,4 +187,5 @@ List searchRemovedByRemoveDate(final Date startDate, final Date en Map getNameIdMapForVmIds(Collection ids); + int getVmCountByOfferingId(Long serviceOfferingId); } diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java index ef10af63bae0..78c5a4bc7b97 100755 --- a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -104,6 +104,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem protected SearchBuilder LastHostAndStatesSearch; protected SearchBuilder VmsNotInClusterUsingPool; protected SearchBuilder IdsPowerStateSelectSearch; + GenericSearchBuilder CountByOfferingId; @Inject ResourceTagDao tagsDao; @@ -344,6 +345,11 @@ protected void init() { IdsPowerStateSelectSearch.entity().getPowerStateUpdateCount(), IdsPowerStateSelectSearch.entity().getPowerStateUpdateTime()); IdsPowerStateSelectSearch.done(); + + CountByOfferingId = createSearchBuilder(Integer.class); + CountByOfferingId.select(null, Func.COUNT, CountByOfferingId.entity().getId()); + CountByOfferingId.and("serviceOfferingId", CountByOfferingId.entity().getServiceOfferingId(), Op.EQ); + CountByOfferingId.done(); } @Override @@ -1224,4 +1230,15 @@ public Map getNameIdMapForVmIds(Collection ids) { return vms.stream() .collect(Collectors.toMap(VMInstanceVO::getInstanceName, VMInstanceVO::getId)); } + + @Override + public int getVmCountByOfferingId(Long serviceOfferingId) { + if (serviceOfferingId == null) { + return 0; + } + SearchCriteria sc = CountByOfferingId.create(); + sc.setParameters("serviceOfferingId", serviceOfferingId); + List count = customSearch(sc, null); + return count.get(0); + } } diff --git a/server/src/main/java/com/cloud/user/DomainManagerImpl.java b/server/src/main/java/com/cloud/user/DomainManagerImpl.java index 6fc9c6f5ef53..9c715c2cf9ee 100644 --- a/server/src/main/java/com/cloud/user/DomainManagerImpl.java +++ b/server/src/main/java/com/cloud/user/DomainManagerImpl.java @@ -34,6 +34,8 @@ import com.cloud.api.query.vo.VpcOfferingJoinVO; import com.cloud.configuration.Resource; import com.cloud.domain.dao.DomainDetailsDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcOfferingDao; import com.cloud.network.vpc.dao.VpcOfferingDetailsDao; import com.cloud.offerings.dao.NetworkOfferingDao; @@ -85,6 +87,7 @@ import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.service.dao.ServiceOfferingDetailsDao; import com.cloud.storage.dao.DiskOfferingDao; +import com.cloud.storage.dao.VolumeDao; import com.cloud.user.dao.AccountDao; import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; @@ -101,6 +104,8 @@ import com.cloud.utils.net.NetUtils; import com.cloud.vm.ReservationContext; import com.cloud.vm.ReservationContextImpl; +import com.cloud.vm.dao.VMInstanceDao; + import org.apache.commons.lang3.StringUtils; @Component @@ -141,6 +146,14 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom @Inject private ProjectDao _projectDao; @Inject + private VMInstanceDao vmInstanceDao; + @Inject + private NetworkDao networkDao; + @Inject + private VolumeDao volumeDao; + @Inject + private VpcDao vpcDao; + @Inject private ProjectManager _projectMgr; @Inject private RegionManager _regionMgr; @@ -543,7 +556,8 @@ private void removeVpcOfferings(Long domainId, String domainIdString) { List vpcOfferingsDetailsToRemove = new ArrayList<>(); List vpcOfferingsForThisDomain = vpcOfferingJoinDao.findByDomainId(domainId); for (VpcOfferingJoinVO vpcOffering : vpcOfferingsForThisDomain) { - if (domainIdString.equals(vpcOffering.getDomainId())) { + int vpcCount = vpcDao.getVpcCountByOfferingId(vpcOffering.getId()); + if (domainIdString.equals(vpcOffering.getDomainId()) && vpcCount == 0) { vpcOfferingDao.remove(vpcOffering.getId()); } else { vpcOfferingsDetailsToRemove.add(vpcOffering.getId()); @@ -558,7 +572,8 @@ private void removeNetworkOfferings(Long domainId, String domainIdString) { List networkOfferingsDetailsToRemove = new ArrayList<>(); List networkOfferingsForThisDomain = networkOfferingJoinDao.findByDomainId(domainId, false); for (NetworkOfferingJoinVO networkOffering : networkOfferingsForThisDomain) { - if (domainIdString.equals(networkOffering.getDomainId())) { + int networkCount = networkDao.getNetworkCountByNetworkOffId(networkOffering.getId()); + if (domainIdString.equals(networkOffering.getDomainId()) && networkCount == 0) { networkOfferingDao.remove(networkOffering.getId()); } else { networkOfferingsDetailsToRemove.add(networkOffering.getId()); @@ -573,7 +588,8 @@ private void removeServiceOfferings(Long domainId, String domainIdString) { List serviceOfferingsDetailsToRemove = new ArrayList<>(); List serviceOfferingsForThisDomain = serviceOfferingJoinDao.findByDomainId(domainId); for (ServiceOfferingJoinVO serviceOffering : serviceOfferingsForThisDomain) { - if (domainIdString.equals(serviceOffering.getDomainId())) { + int vmCount = vmInstanceDao.getVmCountByOfferingId(serviceOffering.getId()); + if (domainIdString.equals(serviceOffering.getDomainId()) && vmCount == 0) { serviceOfferingDao.remove(serviceOffering.getId()); } else { serviceOfferingsDetailsToRemove.add(serviceOffering.getId()); @@ -588,7 +604,8 @@ private void removeDiskOfferings(Long domainId, String domainIdString) { List diskOfferingsDetailsToRemove = new ArrayList<>(); List diskOfferingsForThisDomain = diskOfferingJoinDao.findByDomainId(domainId); for (DiskOfferingJoinVO diskOffering : diskOfferingsForThisDomain) { - if (domainIdString.equals(diskOffering.getDomainId())) { + int volumeCount = volumeDao.getVolumeCountByOfferingId(diskOffering.getId()); + if (domainIdString.equals(diskOffering.getDomainId()) && volumeCount == 0) { diskOfferingDao.remove(diskOffering.getId()); } else { diskOfferingsDetailsToRemove.add(diskOffering.getId());