Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolve merge problems in the backup framework #10457

Merged
merged 5 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 18 additions & 19 deletions api/src/main/java/org/apache/cloudstack/backup/BackupProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,39 +49,38 @@ public interface BackupProvider {

/**
* Assign a VM to a backup offering or policy
* @param vm
* @param backup
* @param policy
* @return
* @param vm the machine to back up
* @param backupOffering the SLA definition for the backup
* @return succeeded?
*/
boolean assignVMToBackupOffering(VirtualMachine vm, BackupOffering backupOffering);

/**
* Removes a VM from a backup offering or policy
* @param vm
* @return
* @param vm the machine to stop backing up
* @return succeeded?
*/
boolean removeVMFromBackupOffering(VirtualMachine vm);

/**
* Whether the provide will delete backups on removal of VM from the offfering
* Whether the provider will delete backups on removal of VM from the offering
* @return boolean result
*/
boolean willDeleteBackupsOnOfferingRemoval();

/**
* Starts and creates an adhoc backup process
* for a previously registered VM backup
* @param backup
* @return
* @param vm the machine to make a backup of
* @return the result and {code}Backup{code} {code}Object{code}
*/
Pair<Boolean, Backup> takeBackup(VirtualMachine vm);

/**
* Delete an existing backup
* @param backuo The backup to exclude
* @param backup The backup to exclude
* @param forced Indicates if backup will be force removed or not
* @return
* @return succeeded?
*/
boolean deleteBackup(Backup backup, boolean forced);

Expand All @@ -97,23 +96,23 @@ public interface BackupProvider {

/**
* Returns backup metrics for a list of VMs in a zone
* @param zoneId
* @param vms
* @return
* @param zoneId the zone for which to return metrics
* @param vms a list of machines to get measurements for
* @return a map of machine -> backup metrics
*/
Map<VirtualMachine, Backup.Metric> getBackupMetrics(Long zoneId, List<VirtualMachine> vms);

/**
* This method should TODO
* @param
* @param vm the machine to get restore point for
*/
public List<Backup.RestorePoint> listRestorePoints(VirtualMachine vm);
List<Backup.RestorePoint> listRestorePoints(VirtualMachine vm);

/**
* This method should TODO
* @param
* @param
* @param metric
* @param restorePoint the restore point to create a backup for
* @param vm The machine for which to create a backup
* @param metric the metric object to update with the new backup data
*/
Backup createNewBackupEntryForRestorePoint(Backup.RestorePoint restorePoint, VirtualMachine vm, Backup.Metric metric);
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@

@Override
public boolean removeVMFromBackupOffering(VirtualMachine vm) {
logger.debug(String.format("Removing VM %s from backup offering by the Dummy Backup Provider", vm));
logger.debug("Removing VM {} from backup offering by the Dummy Backup Provider", vm);

Check warning on line 115 in plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java#L115

Added line #L115 was not covered by tests
return true;
}

Expand All @@ -123,15 +123,15 @@

@Override
public Pair<Boolean, Backup> takeBackup(VirtualMachine vm) {
logger.debug(String.format("Starting backup for VM %s on Dummy provider", vm));
logger.debug("Starting backup for VM {} on Dummy provider", vm);

Check warning on line 126 in plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java#L126

Added line #L126 was not covered by tests

BackupVO backup = new BackupVO();
backup.setVmId(vm.getId());
backup.setExternalId("dummy-external-id");
backup.setType("FULL");
backup.setDate(new Date());
backup.setSize(1024000L);
backup.setProtectedSize(1 * Resource.ResourceType.bytesToGiB);
backup.setProtectedSize(Resource.ResourceType.bytesToGiB);

Check warning on line 134 in plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java#L134

Added line #L134 was not covered by tests
backup.setStatus(Backup.Status.BackedUp);
backup.setBackupOfferingId(vm.getBackupOfferingId());
backup.setAccountId(vm.getAccountId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.apache.cloudstack.backup;

import com.cloud.agent.AgentManager;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.host.Host;
Expand All @@ -36,8 +35,8 @@
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.VMInstanceDao;

import org.apache.cloudstack.backup.dao.BackupDao;
import org.apache.cloudstack.backup.dao.BackupOfferingDao;
import org.apache.cloudstack.backup.dao.BackupRepositoryDao;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
Expand Down Expand Up @@ -70,15 +69,9 @@
@Inject
private BackupRepositoryDao backupRepositoryDao;

@Inject
private BackupOfferingDao backupOfferingDao;

@Inject
private HostDao hostDao;

@Inject
private ClusterDao clusterDao;

@Inject
private VolumeDao volumeDao;

Expand Down Expand Up @@ -108,15 +101,15 @@
// Try to find any Up host in the same cluster
for (final Host hostInCluster : hostDao.findHypervisorHostInCluster(host.getClusterId())) {
if (hostInCluster.getStatus() == Status.Up) {
LOG.debug("Found Host {}", hostInCluster);
LOG.debug("Found Host {} in cluster {}", hostInCluster, host.getClusterId());

Check warning on line 104 in plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java#L104

Added line #L104 was not covered by tests
return hostInCluster;
}
}
}
// Try to find any Host in the zone
for (final HostVO hostInZone : hostDao.listByDataCenterIdAndHypervisorType(host.getDataCenterId(), Hypervisor.HypervisorType.KVM)) {
if (hostInZone.getStatus() == Status.Up) {
LOG.debug("Found Host {}", hostInZone);
LOG.debug("Found Host {} in zone {}", hostInZone, host.getDataCenterId());

Check warning on line 112 in plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java#L112

Added line #L112 was not covered by tests
return hostInZone;
}
}
Expand Down Expand Up @@ -166,7 +159,7 @@
command.setVolumePaths(volumePaths);
}

BackupAnswer answer = null;
BackupAnswer answer;
try {
answer = (BackupAnswer) agentManager.send(host.getId(), command);
} catch (AgentUnavailableException e) {
Expand Down Expand Up @@ -204,7 +197,7 @@
virtualSize += volume.getSize();
}
}
backup.setProtectedSize(Long.valueOf(virtualSize));
backup.setProtectedSize(virtualSize);

Check warning on line 200 in plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java#L200

Added line #L200 was not covered by tests
backup.setStatus(Backup.Status.BackingUp);
backup.setBackupOfferingId(vm.getBackupOfferingId());
backup.setAccountId(vm.getAccountId());
Expand All @@ -231,7 +224,7 @@
restoreCommand.setVmExists(vm.getRemoved() == null);
restoreCommand.setVmState(vm.getState());

BackupAnswer answer = null;
BackupAnswer answer;
try {
answer = (BackupAnswer) agentManager.send(host.getId(), restoreCommand);
} catch (AgentUnavailableException e) {
Expand Down Expand Up @@ -298,7 +291,7 @@
restoreCommand.setVmState(vmNameAndState.second());
restoreCommand.setRestoreVolumeUUID(volumeUuid);

BackupAnswer answer = null;
BackupAnswer answer;
try {
answer = (BackupAnswer) agentManager.send(hostVO.getId(), restoreCommand);
} catch (AgentUnavailableException e) {
Expand Down Expand Up @@ -350,7 +343,7 @@
DeleteBackupCommand command = new DeleteBackupCommand(backup.getExternalId(), backupRepository.getType(),
backupRepository.getAddress(), backupRepository.getMountOptions());

BackupAnswer answer = null;
BackupAnswer answer;
try {
answer = (BackupAnswer) agentManager.send(host.getId(), command);
} catch (AgentUnavailableException e) {
Expand All @@ -363,7 +356,7 @@
return backupDao.remove(backup.getId());
}

logger.debug("There was an error removing the backup with id " + backup.getId());
logger.debug("There was an error removing the backup with id {}", backup.getId());

Check warning on line 359 in plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java#L359

Added line #L359 was not covered by tests
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.utils.script.Script;
import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
Expand All @@ -34,6 +35,7 @@
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.VMInstanceDao;

import org.apache.cloudstack.backup.dao.BackupDao;
import org.apache.cloudstack.backup.dao.BackupOfferingDaoImpl;
import org.apache.cloudstack.backup.networker.NetworkerClient;
Expand All @@ -44,7 +46,9 @@
import org.apache.logging.log4j.LogManager;
import org.apache.xml.utils.URI;
import org.apache.cloudstack.backup.networker.api.NetworkerBackup;

import javax.inject.Inject;

import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
Expand All @@ -60,7 +64,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.cloud.utils.script.Script;

public class NetworkerBackupProvider extends AdapterBase implements BackupProvider, Configurable {

Expand Down Expand Up @@ -169,7 +172,7 @@
List<HostVO> altClusterHosts = hostDao.findHypervisorHostInCluster(host.getClusterId());
for (final HostVO candidateClusterHost : altClusterHosts) {
if ( candidateClusterHost.getStatus() == Status.Up ) {
LOG.debug(String.format("Found Host %s", candidateClusterHost));
LOG.debug("Found Host {}", candidateClusterHost);

Check warning on line 175 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L175

Added line #L175 was not covered by tests
return candidateClusterHost;
}
}
Expand All @@ -178,7 +181,7 @@
List<HostVO> altZoneHosts = hostDao.findByDataCenterId(host.getDataCenterId());
for (final HostVO candidateZoneHost : altZoneHosts) {
if ( candidateZoneHost.getStatus() == Status.Up && candidateZoneHost.getHypervisorType() == Hypervisor.HypervisorType.KVM ) {
LOG.debug("Found Host " + candidateZoneHost);
LOG.debug("Found Host {}", candidateZoneHost);

Check warning on line 184 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L184

Added line #L184 was not covered by tests
return candidateZoneHost;
}
}
Expand Down Expand Up @@ -229,13 +232,13 @@
Pair<Boolean, String> response = SshHelper.sshExecute(host.getPrivateIpAddress(), 22,
username, null, password, command, 120000, 120000, 3600000);
if (!response.first()) {
LOG.error(String.format("Backup Script failed on HYPERVISOR %s due to: %s", host, response.second()));
LOG.error("Backup Script failed on HYPERVISOR {} due to: {}", host, response.second());

Check warning on line 235 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L235

Added line #L235 was not covered by tests
} else {
LOG.debug(String.format("Networker Backup Results: %s", response.second()));
LOG.debug("Networker Backup Results: {}", response.second());

Check warning on line 237 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L237

Added line #L237 was not covered by tests
}
Matcher saveTimeMatcher = saveTimePattern.matcher(response.second());
if (saveTimeMatcher.find()) {
LOG.debug(String.format("Got saveTimeMatcher: %s", saveTimeMatcher.group(1)));
LOG.debug("Got saveTimeMatcher: {}", saveTimeMatcher.group(1));

Check warning on line 241 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L241

Added line #L241 was not covered by tests
return saveTimeMatcher.group(1);
}
} catch (final Exception e) {
Expand All @@ -251,9 +254,9 @@
username, null, password, command, 120000, 120000, 3600000);

if (!response.first()) {
LOG.error(String.format("Restore Script failed on HYPERVISOR %s due to: %s", host, response.second()));
LOG.error("Restore Script failed on HYPERVISOR {} due to: {}", host, response.second());

Check warning on line 257 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L257

Added line #L257 was not covered by tests
} else {
LOG.debug(String.format("Networker Restore Results: %s",response.second()));
LOG.debug("Networker Restore Results: {}",response.second());

Check warning on line 259 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L259

Added line #L259 was not covered by tests
return true;
}
} catch (final Exception e) {
Expand Down Expand Up @@ -310,7 +313,7 @@
List<String> backupsTaken = getClient(vm.getDataCenterId()).getBackupsForVm(vm);

for (String backupId : backupsTaken) {
LOG.debug("Trying to remove backup with id" + backupId);
LOG.debug("Trying to remove backup with id {}", backupId);

Check warning on line 316 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L316

Added line #L316 was not covered by tests
getClient(vm.getDataCenterId()).deleteBackupForVM(backupId);
}

Expand All @@ -327,18 +330,18 @@
final NetworkerBackup networkerBackup=getClient(zoneId).getNetworkerBackupInfo(externalBackupId);
final String SSID = networkerBackup.getShortId();

LOG.debug(String.format("Restoring vm %s from backup %s on the Networker Backup Provider", vm, backup));
LOG.debug("Restoring vm {} from backup {} on the Networker Backup Provider", vm, backup);

Check warning on line 333 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L333

Added line #L333 was not covered by tests

if ( SSID.isEmpty() ) {
LOG.debug("There was an error retrieving the SSID for backup with id " + externalBackupId + " from EMC NEtworker");
LOG.debug("There was an error retrieving the SSID for backup with id {} from EMC NEtworker", externalBackupId);

Check warning on line 336 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L336

Added line #L336 was not covered by tests
return false;
}

// Find where the VM was last running
hostVO = getLastVMHypervisorHost(vm);
// Get credentials for that host
Ternary<String, String, String> credentials = getKVMHyperisorCredentials(hostVO);
LOG.debug("The SSID was reported successfully " + externalBackupId);
LOG.debug("The SSID was reported successfully {}", externalBackupId);

Check warning on line 344 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L344

Added line #L344 was not covered by tests
try {
networkerServer = getUrlDomain(NetworkerUrl.value());
} catch (URISyntaxException e) {
Expand All @@ -355,14 +358,14 @@
script.add("-v");

Date restoreJobStart = new Date();
LOG.debug(String.format("Starting Restore for VM %s and %s at %s", vm, SSID, restoreJobStart));
LOG.debug("Starting Restore for VM {} and {} at {}", vm, SSID, restoreJobStart);

Check warning on line 361 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L361

Added line #L361 was not covered by tests

if ( executeRestoreCommand(hostVO, credentials.first(), credentials.second(), script.toString()) ) {
Date restoreJobEnd = new Date();
LOG.debug("Restore Job for SSID " + SSID + " completed successfully at " + restoreJobEnd);
LOG.debug("Restore Job for SSID {} completed successfully at {}", SSID, restoreJobEnd);

Check warning on line 365 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L365

Added line #L365 was not covered by tests
return true;
} else {
LOG.debug("Restore Job for SSID " + SSID + " failed!");
LOG.debug("Restore Job for SSID {} failed!", SSID);

Check warning on line 368 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L368

Added line #L368 was not covered by tests
return false;
}
}
Expand All @@ -383,7 +386,7 @@
final String destinationNetworkerClient = hostVO.getName().split("\\.")[0];
Long restoredVolumeDiskSize = 0L;

LOG.debug(String.format("Restoring volume %s with uuid %s from backup %s on the Networker Backup Provider", volume, volumeUuid, backup));
LOG.debug("Restoring volume {} with uuid {} from backup {} on the Networker Backup Provider", volume, volumeUuid, backup);

Check warning on line 389 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L389

Added line #L389 was not covered by tests

if ( SSID.isEmpty() ) {
LOG.debug("There was an error retrieving the SSID for backup with id " + externalBackupId + " from EMC NEtworker");
Expand Down Expand Up @@ -536,8 +539,8 @@
@Override
public Map<VirtualMachine, Backup.Metric> getBackupMetrics(Long zoneId, List<VirtualMachine> vms) {
final Map<VirtualMachine, Backup.Metric> metrics = new HashMap<>();
Long vmBackupSize=0L;
Long vmBackupProtectedSize=0L;
long vmBackupSize=0L;
long vmBackupProtectedSize=0L;

Check warning on line 543 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L542-L543

Added lines #L542 - L543 were not covered by tests

if (CollectionUtils.isEmpty(vms)) {
LOG.warn("Unable to get VM Backup Metrics because the list of VMs is empty.");
Expand Down Expand Up @@ -584,7 +587,7 @@
throw new CloudRuntimeException(msg, e);
}
backup.setStatus(Backup.Status.BackedUp);
Long vmBackupProtectedSize=0L;
long vmBackupProtectedSize=0L;

Check warning on line 590 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L590

Added line #L590 was not covered by tests
for (Backup.VolumeInfo thisVMVol : vm.getBackupVolumeList()) {
vmBackupProtectedSize += (thisVMVol.getSize() / 1024L / 1024L);
}
Expand All @@ -605,9 +608,7 @@
public List<Backup.RestorePoint> listRestorePoints(VirtualMachine vm) {
final Long zoneId = vm.getDataCenterId();
final ArrayList<String> backupIds = getClient(zoneId).getBackupsForVm(vm);
List<Backup.RestorePoint> restorePoints =
backupIds.stream().map(id -> new Backup.RestorePoint(id, null, null)).collect(Collectors.toList());
return restorePoints;
return backupIds.stream().map(id -> new Backup.RestorePoint(id, null, null)).collect(Collectors.toList());

Check warning on line 611 in plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

View check run for this annotation

Codecov / codecov/patch

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java#L611

Added line #L611 was not covered by tests
}

@Override
Expand Down
Loading
Loading