From c40b30bc4a02e0661619ce98c0a1e51d14ddec53 Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Tue, 14 Apr 2026 21:20:41 +0530 Subject: [PATCH] Remove ImagetransferProgress Command --- .../api/response/ImageTransferResponse.java | 8 -- .../backup/KVMBackupExportService.java | 5 - .../GetImageTransferProgressAnswer.java | 47 -------- .../GetImageTransferProgressCommand.java | 67 ----------- .../cloudstack/backup/ImageTransferVO.java | 12 -- ...etImageTransferProgressCommandWrapper.java | 95 --------------- ...ageTransferVOToImageTransferConverter.java | 2 +- .../backup/KVMBackupExportServiceImpl.java | 108 ------------------ 8 files changed, 1 insertion(+), 343 deletions(-) delete mode 100644 core/src/main/java/org/apache/cloudstack/backup/GetImageTransferProgressAnswer.java delete mode 100644 core/src/main/java/org/apache/cloudstack/backup/GetImageTransferProgressCommand.java delete mode 100644 plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetImageTransferProgressCommandWrapper.java diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ImageTransferResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ImageTransferResponse.java index 8a24ed3966f..15576e8f101 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/ImageTransferResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/ImageTransferResponse.java @@ -62,10 +62,6 @@ public class ImageTransferResponse extends BaseResponse { @Param(description = "the image transfer direction: upload / download") private String direction; - @SerializedName("progress") - @Param(description = "progress in percentage for the upload image transfer") - private Integer progress; - @SerializedName(ApiConstants.CREATED) @Param(description = "the date created") private Date created; @@ -102,10 +98,6 @@ public class ImageTransferResponse extends BaseResponse { this.direction = direction; } - public void setProgress(Integer progress) { - this.progress = progress; - } - public void setCreated(Date created) { this.created = created; } diff --git a/api/src/main/java/org/apache/cloudstack/backup/KVMBackupExportService.java b/api/src/main/java/org/apache/cloudstack/backup/KVMBackupExportService.java index 51e52c85ec3..a40b2b5b5ed 100644 --- a/api/src/main/java/org/apache/cloudstack/backup/KVMBackupExportService.java +++ b/api/src/main/java/org/apache/cloudstack/backup/KVMBackupExportService.java @@ -38,11 +38,6 @@ import com.cloud.utils.component.PluggableService; */ public interface KVMBackupExportService extends Configurable, PluggableService { - ConfigKey ImageTransferPollingInterval = new ConfigKey<>("Advanced", Long.class, - "image.transfer.polling.interval", - "10", - "The image transfer progress polling interval in seconds.", true, ConfigKey.Scope.Global); - ConfigKey ImageTransferIdleTimeoutSeconds = new ConfigKey<>("Advanced", Integer.class, "image.transfer.idle.timeout.seconds", "600", diff --git a/core/src/main/java/org/apache/cloudstack/backup/GetImageTransferProgressAnswer.java b/core/src/main/java/org/apache/cloudstack/backup/GetImageTransferProgressAnswer.java deleted file mode 100644 index 5b5713f4683..00000000000 --- a/core/src/main/java/org/apache/cloudstack/backup/GetImageTransferProgressAnswer.java +++ /dev/null @@ -1,47 +0,0 @@ -//Licensed to the Apache Software Foundation (ASF) under one -//or more contributor license agreements. See the NOTICE file -//distributed with this work for additional information -//regarding copyright ownership. The ASF licenses this file -//to you under the Apache License, Version 2.0 (the -//"License"); you may not use this file except in compliance -//the License. You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, -//software distributed under the License is distributed on an -//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -//KIND, either express or implied. See the License for the -//specific language governing permissions and limitations -//under the License. - -package org.apache.cloudstack.backup; - -import java.util.Map; - -import com.cloud.agent.api.Answer; - -public class GetImageTransferProgressAnswer extends Answer { - private Map progressMap; // transferId -> progress percentage (0-100) - - public GetImageTransferProgressAnswer() { - } - - public GetImageTransferProgressAnswer(GetImageTransferProgressCommand cmd, boolean success, String details) { - super(cmd, success, details); - } - - public GetImageTransferProgressAnswer(GetImageTransferProgressCommand cmd, boolean success, String details, - Map progressMap) { - super(cmd, success, details); - this.progressMap = progressMap; - } - - public Map getProgressMap() { - return progressMap; - } - - public void setProgressMap(Map progressMap) { - this.progressMap = progressMap; - } -} diff --git a/core/src/main/java/org/apache/cloudstack/backup/GetImageTransferProgressCommand.java b/core/src/main/java/org/apache/cloudstack/backup/GetImageTransferProgressCommand.java deleted file mode 100644 index 2391f957f51..00000000000 --- a/core/src/main/java/org/apache/cloudstack/backup/GetImageTransferProgressCommand.java +++ /dev/null @@ -1,67 +0,0 @@ -//Licensed to the Apache Software Foundation (ASF) under one -//or more contributor license agreements. See the NOTICE file -//distributed with this work for additional information -//regarding copyright ownership. The ASF licenses this file -//to you under the Apache License, Version 2.0 (the -//"License"); you may not use this file except in compliance -//the License. You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, -//software distributed under the License is distributed on an -//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -//KIND, either express or implied. See the License for the -//specific language governing permissions and limitations -//under the License. - -package org.apache.cloudstack.backup; - -import java.util.List; -import java.util.Map; - -import com.cloud.agent.api.Command; - -public class GetImageTransferProgressCommand extends Command { - private List transferIds; - private Map volumePaths; // transferId -> volume path - private Map volumeSizes; // transferId -> volume size - - public GetImageTransferProgressCommand() { - } - - public GetImageTransferProgressCommand(List transferIds, Map volumePaths, Map volumeSizes) { - this.transferIds = transferIds; - this.volumePaths = volumePaths; - this.volumeSizes = volumeSizes; - } - - public List getTransferIds() { - return transferIds; - } - - public void setTransferIds(List transferIds) { - this.transferIds = transferIds; - } - - public Map getVolumePaths() { - return volumePaths; - } - - public void setVolumePaths(Map volumePaths) { - this.volumePaths = volumePaths; - } - - public Map getVolumeSizes() { - return volumeSizes; - } - - public void setVolumeSizes(Map volumeSizes) { - this.volumeSizes = volumeSizes; - } - - @Override - public boolean executeInSequence() { - return false; - } -} diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/ImageTransferVO.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/ImageTransferVO.java index 7c8af972bbe..ec9b927b63e 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/backup/ImageTransferVO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/ImageTransferVO.java @@ -75,9 +75,6 @@ public class ImageTransferVO implements ImageTransfer { @Column(name = "signed_ticket_id") private String signedTicketId; - @Column(name = "progress") - private Integer progress; - @Column(name = "account_id") Long accountId; @@ -210,15 +207,6 @@ public class ImageTransferVO implements ImageTransfer { this.signedTicketId = signedTicketId; } - public Integer getProgress() { - return progress; - } - - public void setProgress(Integer progress) { - this.progress = progress; - this.updated = new Date(); - } - @Override public Class getEntityType() { return ImageTransfer.class; diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetImageTransferProgressCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetImageTransferProgressCommandWrapper.java deleted file mode 100644 index 7e0cbf2934d..00000000000 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetImageTransferProgressCommandWrapper.java +++ /dev/null @@ -1,95 +0,0 @@ -//Licensed to the Apache Software Foundation (ASF) under one -//or more contributor license agreements. See the NOTICE file -//distributed with this work for additional information -//regarding copyright ownership. The ASF licenses this file -//to you under the Apache License, Version 2.0 (the -//"License"); you may not use this file except in compliance -//the License. You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, -//software distributed under the License is distributed on an -//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -//KIND, either express or implied. See the License for the -//specific language governing permissions and limitations -//under the License. - -package com.cloud.hypervisor.kvm.resource.wrapper; - -import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.cloudstack.backup.GetImageTransferProgressAnswer; -import org.apache.cloudstack.backup.GetImageTransferProgressCommand; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import com.cloud.agent.api.Answer; -import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; -import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; -import com.cloud.resource.CommandWrapper; -import com.cloud.resource.ResourceWrapper; - -@ResourceWrapper(handles = GetImageTransferProgressCommand.class) -public class LibvirtGetImageTransferProgressCommandWrapper extends CommandWrapper { - protected Logger logger = LogManager.getLogger(getClass()); - - @Override - public Answer execute(GetImageTransferProgressCommand cmd, LibvirtComputingResource resource) { - try { - List transferIds = cmd.getTransferIds(); - Map volumePaths = cmd.getVolumePaths(); - Map volumeSizes = cmd.getVolumeSizes(); - Map progressMap = new HashMap<>(); - - if (transferIds == null || transferIds.isEmpty()) { - return new GetImageTransferProgressAnswer(cmd, true, "No transfers to check", progressMap); - } - - for (String transferId : transferIds) { - String volumePath = volumePaths.get(transferId); - Long volumeSize = volumeSizes.get(transferId); - - if (volumePath == null || volumeSize == null || volumeSize == 0) { - logger.warn("Missing volume path or size for transferId: {}", transferId); - progressMap.put(transferId, null); - continue; - } - - try { - File file = new File(volumePath); - if (!file.exists()) { - logger.warn("Volume file does not exist: {}", volumePath); - progressMap.put(transferId, null); - continue; - } - - long currentSize = file.length(); - - if (volumePath.endsWith(".qcow2") || volumePath.endsWith(".qcow")) { - try { - currentSize = KVMPhysicalDisk.getVirtualSizeFromFile(volumePath); - } catch (Exception e) { - logger.warn("Failed to get virtual size for qcow2 file: {}, using physical size", volumePath, e); - } - } - progressMap.put(transferId, currentSize); - logger.debug("Transfer {} progress, current: {})", transferId, currentSize, volumeSize); - - } catch (Exception e) { - logger.error("Error getting progress for transferId: {}, path: {}", transferId, volumePath, e); - progressMap.put(transferId, null); - } - } - - return new GetImageTransferProgressAnswer(cmd, true, "Progress retrieved successfully", progressMap); - - } catch (Exception e) { - logger.error("Error executing GetImageTransferProgressCommand", e); - return new GetImageTransferProgressAnswer(cmd, false, "Error getting transfer progress: " + e.getMessage()); - } - } -} diff --git a/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/ImageTransferVOToImageTransferConverter.java b/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/ImageTransferVOToImageTransferConverter.java index 98b0baa1e13..3be1865895a 100644 --- a/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/ImageTransferVOToImageTransferConverter.java +++ b/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/ImageTransferVOToImageTransferConverter.java @@ -42,7 +42,7 @@ public class ImageTransferVOToImageTransferConverter { final String basePath = VeeamControlService.ContextPath.value(); imageTransfer.setId(vo.getUuid()); imageTransfer.setHref(basePath + ImageTransfersRouteHandler.BASE_ROUTE + "/" + vo.getUuid()); - imageTransfer.setActive(Boolean.toString(vo.getProgress() != null && vo.getProgress() > 0 && vo.getProgress() < 100)); + imageTransfer.setActive(Boolean.toString(org.apache.cloudstack.backup.ImageTransfer.Phase.transferring.equals(vo.getPhase()))); imageTransfer.setDirection(vo.getDirection().name()); imageTransfer.setFormat("cow"); imageTransfer.setInactivityTimeout(Integer.toString(3600)); diff --git a/server/src/main/java/org/apache/cloudstack/backup/KVMBackupExportServiceImpl.java b/server/src/main/java/org/apache/cloudstack/backup/KVMBackupExportServiceImpl.java index e9de55a20d3..57a09453144 100644 --- a/server/src/main/java/org/apache/cloudstack/backup/KVMBackupExportServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/backup/KVMBackupExportServiceImpl.java @@ -28,9 +28,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import javax.inject.Inject; @@ -53,10 +50,8 @@ import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO; import org.apache.cloudstack.jobs.JobInfo; -import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.springframework.stereotype.Component; @@ -84,7 +79,6 @@ import com.cloud.user.AccountService; import com.cloud.user.User; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; -import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.ReflectionUse; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; @@ -142,8 +136,6 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup @Inject AsyncJobManager asyncJobManager; - private ScheduledExecutorService imageTransferStatusExecutor; - VmWorkJobHandlerProxy jobHandlerProxy = new VmWorkJobHandlerProxy(this); private boolean isKVMBackupExportServiceSupported(Long zoneId) { @@ -878,7 +870,6 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup response.setDiskId(volume.getUuid()); response.setTransferUrl(imageTransferVO.getTransferUrl()); response.setPhase(imageTransferVO.getPhase().toString()); - response.setProgress(imageTransferVO.getProgress()); response.setDirection(imageTransferVO.getDirection().toString()); response.setCreated(imageTransferVO.getCreated()); return response; @@ -886,24 +877,11 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup @Override public boolean start() { - imageTransferStatusExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Image-Transfer-Status-Executor")); - long pollingInterval = ImageTransferPollingInterval.value(); - imageTransferStatusExecutor.scheduleAtFixedRate(new ManagedContextRunnable() { - @Override - protected void runInContext() { - try { - pollImageTransferProgress(); - } catch (final Throwable t) { - logger.warn("Catch throwable in image transfer poll task ", t); - } - } - }, pollingInterval, pollingInterval, TimeUnit.SECONDS); return true; } @Override public boolean stop() { - imageTransferStatusExecutor.shutdown(); return true; } @@ -945,91 +923,6 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup } } - private void pollImageTransferProgress() { - try { - List transferringTransfers = imageTransferDao.listByPhaseAndDirection( - ImageTransfer.Phase.transferring, ImageTransfer.Direction.upload); - if (transferringTransfers == null || transferringTransfers.isEmpty()) { - return; - } - - Map> transfersByHost = transferringTransfers.stream() - .collect(Collectors.groupingBy(ImageTransferVO::getHostId)); - Map transferVolumeMap = new HashMap<>(); - - for (Map.Entry> entry : transfersByHost.entrySet()) { - Long hostId = entry.getKey(); - List hostTransfers = entry.getValue(); - - try { - List transferIds = new ArrayList<>(); - Map volumePaths = new HashMap<>(); - Map volumeSizes = new HashMap<>(); - - for (ImageTransferVO transfer : hostTransfers) { - VolumeVO volume = volumeDao.findById(transfer.getVolumeId()); - if (volume == null) { - logger.warn("Volume not found for image transfer: {}", transfer.getUuid()); - imageTransferDao.remove(transfer.getId()); - continue; - } - transferVolumeMap.put(transfer.getId(), volume); - - String transferId = transfer.getUuid(); - transferIds.add(transferId); - - if (volume.getPath() == null) { - logger.warn("Volume path is null for image transfer: {}", transfer.getUuid()); - continue; - } - String volumePath = getVolumePathForFileBasedBackend(volume); - volumePaths.put(transferId, volumePath); - volumeSizes.put(transferId, volume.getSize()); - } - - if (transferIds.isEmpty()) { - continue; - } - - GetImageTransferProgressCommand cmd = new GetImageTransferProgressCommand(transferIds, volumePaths, volumeSizes); - GetImageTransferProgressAnswer answer = (GetImageTransferProgressAnswer) agentManager.send(hostId, cmd); - - if (answer == null || !answer.getResult() || MapUtils.isEmpty(answer.getProgressMap())) { - logger.warn("Failed to get progress for transfers on host {}: {}", hostId, - answer != null ? answer.getDetails() : "null answer"); - continue; - } - - for (ImageTransferVO transfer : hostTransfers) { - String transferId = transfer.getUuid(); - Long currentSize = answer.getProgressMap().get(transferId); - if (currentSize == null) { - continue; - } - VolumeVO volume = transferVolumeMap.get(transfer.getId()); - long totalSize = getVolumeTotalSize(volume); - int progress = Math.max((int)((currentSize * 100) / totalSize), 100); - transfer.setProgress(progress); - if (currentSize >= 100) { - transfer.setPhase(ImageTransfer.Phase.finished); - logger.debug("Updated phase for image transfer {} to finished", transferId); - } - imageTransferDao.update(transfer.getId(), transfer); - logger.debug("Updated progress for image transfer {}: {}%", transferId, progress); - } - - } catch (AgentUnavailableException | OperationTimedoutException e) { - logger.warn("Failed to communicate with host {} for image transfer progress", hostId); - } catch (Exception e) { - logger.error("Error polling image transfer progress for host " + hostId, e); - } - } - - } catch (Exception e) { - logger.error("Error in pollImageTransferProgress", e); - } - } - private long getVolumeTotalSize(VolumeVO volume) { VolumeDetailVO detail = volumeDetailsDao.findDetail(volume.getId(), ApiConstants.VIRTUAL_SIZE); if (detail != null) { @@ -1063,7 +956,6 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup @Override public ConfigKey[] getConfigKeys() { return new ConfigKey[]{ - ImageTransferPollingInterval, ImageTransferIdleTimeoutSeconds, ExposeKVMBackupExportServiceApis };