rearrange logic for change of ownership to avoid any resources being left behind in the DB should there be an exception

This commit is contained in:
Pearl Dsilva 2025-05-13 09:51:02 +05:30
parent caa8c8183b
commit fd7159cd5a
2 changed files with 23 additions and 34 deletions

View File

@ -7581,20 +7581,33 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
protected void executeStepsToChangeOwnershipOfVm(AssignVMCmd cmd, Account caller, Account oldAccount, Account newAccount, UserVmVO vm, ServiceOfferingVO offering,
List<VolumeVO> volumes, VirtualMachineTemplate template, Long domainId) {
logger.trace("Generating destroy event for VM [{}].", vm);
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(),
vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
logger.trace("Decrementing old account [{}] resource count.", oldAccount);
resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), offering, template);
logger.trace("Removing VM [{}] from its instance group.", vm);
removeInstanceFromInstanceGroup(vm.getId());
Long newAccountId = newAccount.getAccountId();
AtomicBoolean isNetworkAutoCreated = new AtomicBoolean(false);
try {
updateVmNetwork(cmd, caller, vm, newAccount, template, isNetworkAutoCreated);
logger.trace("Generating destroy event for VM [{}].", vm);
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(),
vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
logger.trace("Decrementing old account [{}] resource count.", oldAccount);
resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), offering, template);
logger.trace("Removing VM [{}] from its instance group.", vm);
removeInstanceFromInstanceGroup(vm.getId());
updateVmOwner(newAccount, vm, domainId, newAccountId);
updateVolumesOwner(volumes, oldAccount, newAccount, newAccountId);
logger.trace(String.format("Incrementing new account [%s] resource count.", newAccount));
if (!isResourceCountRunningVmsOnlyEnabled()) {
resourceCountIncrement(newAccountId, vm.isDisplayVm(), offering, template);
}
logger.trace(String.format("Generating create event for VM [%s].", vm));
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(),
vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
} catch (InsufficientCapacityException | ResourceAllocationException e) {
List<NetworkVO> networkVOS = _networkDao.listByAccountIdNetworkName(newAccountId, newAccount.getAccountName() + "-network");
if (networkVOS.size() == 1 && isNetworkAutoCreated.get()) {
@ -7602,19 +7615,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
throw new CloudRuntimeException(String.format("Unable to update networks when assigning VM [%s] due to [%s].", vm, e.getMessage()), e);
}
updateVmOwner(newAccount, vm, domainId, newAccountId);
updateVolumesOwner(volumes, oldAccount, newAccount, newAccountId);
logger.trace(String.format("Incrementing new account [%s] resource count.", newAccount));
if (!isResourceCountRunningVmsOnlyEnabled()) {
resourceCountIncrement(newAccountId, vm.isDisplayVm(), offering, template);
}
logger.trace(String.format("Generating create event for VM [%s].", vm));
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(),
vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
}
protected void updateVmOwner(Account newAccount, UserVmVO vm, Long domainId, Long newAccountId) {

View File

@ -3055,8 +3055,6 @@ public class UserVmManagerImplTest {
LinkedList<VolumeVO> volumes = new LinkedList<VolumeVO>();
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class)) {
Mockito.doReturn(Hypervisor.HypervisorType.KVM).when(userVmVoMock).getHypervisorType();
configureDoNothingForMethodsThatWeDoNotWantToTest();
Mockito.doThrow(InsufficientAddressCapacityException.class).when(userVmManagerImpl).updateVmNetwork(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
@ -3064,10 +3062,6 @@ public class UserVmManagerImplTest {
Assert.assertThrows(CloudRuntimeException.class, () -> userVmManagerImpl.executeStepsToChangeOwnershipOfVm(assignVmCmdMock, callerAccount, accountMock, accountMock,
userVmVoMock, serviceOfferingVoMock, volumes, virtualMachineTemplateMock, 1l));
Mockito.verify(userVmManagerImpl).resourceCountDecrement(Mockito.anyLong(), Mockito.any(), Mockito.any(), Mockito.any());
Mockito.verify(userVmManagerImpl).updateVmOwner(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.anyLong());
Mockito.verify(userVmManagerImpl).updateVolumesOwner(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyLong());
}
}
@ -3078,8 +3072,6 @@ public class UserVmManagerImplTest {
LinkedList<VolumeVO> volumes = new LinkedList<VolumeVO>();
try (MockedStatic<UsageEventUtils> ignored = Mockito.mockStatic(UsageEventUtils.class)) {
Mockito.doReturn(Hypervisor.HypervisorType.KVM).when(userVmVoMock).getHypervisorType();
configureDoNothingForMethodsThatWeDoNotWantToTest();
Mockito.doThrow(ResourceAllocationException.class).when(userVmManagerImpl).updateVmNetwork(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
@ -3088,9 +3080,6 @@ public class UserVmManagerImplTest {
Assert.assertThrows(CloudRuntimeException.class, () -> userVmManagerImpl.executeStepsToChangeOwnershipOfVm(assignVmCmdMock, callerAccount, accountMock, accountMock,
userVmVoMock, serviceOfferingVoMock, volumes, virtualMachineTemplateMock, 1l));
Mockito.verify(userVmManagerImpl).resourceCountDecrement(Mockito.anyLong(), Mockito.any(), Mockito.any(), Mockito.any());
Mockito.verify(userVmManagerImpl).updateVmOwner(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.anyLong());
Mockito.verify(userVmManagerImpl).updateVolumesOwner(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyLong());
}
}