2929
3030import javax .inject .Inject ;
3131
32- import org .apache .cloudstack .api .ApiCommandResourceType ;
33- import org .apache .cloudstack .api .InternalIdentity ;
3432import org .apache .cloudstack .backup .Backup .Metric ;
3533import org .apache .cloudstack .backup .dao .BackupDao ;
3634import org .apache .cloudstack .backup .veeam .VeeamClient ;
4240
4341import com .cloud .agent .AgentManager ;
4442import com .cloud .agent .api .Answer ;
45- import com .cloud .event .ActionEventUtils ;
46- import com .cloud .event .EventTypes ;
47- import com .cloud .event .EventVO ;
4843import com .cloud .hypervisor .Hypervisor ;
4944import com .cloud .dc .VmwareDatacenter ;
50- import com .cloud .dc .dao .VmwareDatacenterDao ;
5145import com .cloud .hypervisor .vmware .VmwareDatacenterZoneMap ;
46+ import com .cloud .dc .dao .VmwareDatacenterDao ;
5247import com .cloud .hypervisor .vmware .dao .VmwareDatacenterZoneMapDao ;
53- import com .cloud .storage .dao .VolumeDao ;
54- import com .cloud .user .User ;
5548import com .cloud .utils .Pair ;
5649import com .cloud .utils .component .AdapterBase ;
57- import com .cloud .utils .db .Transaction ;
58- import com .cloud .utils .db .TransactionCallbackNoReturn ;
59- import com .cloud .utils .db .TransactionStatus ;
6050import com .cloud .utils .exception .CloudRuntimeException ;
6151import com .cloud .vm .VMInstanceVO ;
6252import com .cloud .vm .VirtualMachine ;
@@ -75,27 +65,27 @@ public class VeeamBackupProvider extends AdapterBase implements BackupProvider,
7565 "backup.plugin.veeam.version" , "0" ,
7666 "The version of Veeam backup and recovery. CloudStack will get Veeam server version via PowerShell commands if it is 0 or not set" , true , ConfigKey .Scope .Zone );
7767
78- private final ConfigKey <String > VeeamUsername = new ConfigKey <>("Advanced" , String .class ,
68+ private ConfigKey <String > VeeamUsername = new ConfigKey <>("Advanced" , String .class ,
7969 "backup.plugin.veeam.username" , "administrator" ,
8070 "The Veeam backup and recovery username." , true , ConfigKey .Scope .Zone );
8171
82- private final ConfigKey <String > VeeamPassword = new ConfigKey <>("Secure" , String .class ,
72+ private ConfigKey <String > VeeamPassword = new ConfigKey <>("Secure" , String .class ,
8373 "backup.plugin.veeam.password" , "" ,
8474 "The Veeam backup and recovery password." , true , ConfigKey .Scope .Zone );
8575
86- private final ConfigKey <Boolean > VeeamValidateSSLSecurity = new ConfigKey <>("Advanced" , Boolean .class , "backup.plugin.veeam.validate.ssl" , "false" ,
76+ private ConfigKey <Boolean > VeeamValidateSSLSecurity = new ConfigKey <>("Advanced" , Boolean .class , "backup.plugin.veeam.validate.ssl" , "false" ,
8777 "When set to true, this will validate the SSL certificate when connecting to https/ssl enabled Veeam API service." , true , ConfigKey .Scope .Zone );
8878
89- private final ConfigKey <Integer > VeeamApiRequestTimeout = new ConfigKey <>("Advanced" , Integer .class , "backup.plugin.veeam.request.timeout" , "300" ,
79+ private ConfigKey <Integer > VeeamApiRequestTimeout = new ConfigKey <>("Advanced" , Integer .class , "backup.plugin.veeam.request.timeout" , "300" ,
9080 "The Veeam B&R API request timeout in seconds." , true , ConfigKey .Scope .Zone );
9181
92- private static final ConfigKey <Integer > VeeamRestoreTimeout = new ConfigKey <>("Advanced" , Integer .class , "backup.plugin.veeam.restore.timeout" , "600" ,
82+ private static ConfigKey <Integer > VeeamRestoreTimeout = new ConfigKey <>("Advanced" , Integer .class , "backup.plugin.veeam.restore.timeout" , "600" ,
9383 "The Veeam B&R API restore backup timeout in seconds." , true , ConfigKey .Scope .Zone );
9484
95- private static final ConfigKey <Integer > VeeamTaskPollInterval = new ConfigKey <>("Advanced" , Integer .class , "backup.plugin.veeam.task.poll.interval" , "5" ,
85+ private static ConfigKey <Integer > VeeamTaskPollInterval = new ConfigKey <>("Advanced" , Integer .class , "backup.plugin.veeam.task.poll.interval" , "5" ,
9686 "The time interval in seconds when the management server polls for Veeam task status." , true , ConfigKey .Scope .Zone );
9787
98- private static final ConfigKey <Integer > VeeamTaskPollMaxRetry = new ConfigKey <>("Advanced" , Integer .class , "backup.plugin.veeam.task.poll.max.retry" , "120" ,
88+ private static ConfigKey <Integer > VeeamTaskPollMaxRetry = new ConfigKey <>("Advanced" , Integer .class , "backup.plugin.veeam.task.poll.max.retry" , "120" ,
9989 "The max number of retrying times when the management server polls for Veeam task status." , true , ConfigKey .Scope .Zone );
10090
10191 @ Inject
@@ -110,8 +100,6 @@ public class VeeamBackupProvider extends AdapterBase implements BackupProvider,
110100 private AgentManager agentMgr ;
111101 @ Inject
112102 private VirtualMachineManager virtualMachineManager ;
113- @ Inject
114- private VolumeDao volumeDao ;
115103
116104 protected VeeamClient getClient (final Long zoneId ) {
117105 try {
@@ -202,15 +190,15 @@ public boolean removeVMFromBackupOffering(final VirtualMachine vm) {
202190 final VmwareDatacenter vmwareDC = findVmwareDatacenterForVM (vm );
203191 try {
204192 if (!client .removeVMFromVeeamJob (vm .getBackupExternalId (), vm .getInstanceName (), vmwareDC .getVcenterHost ())) {
205- logger .warn ("Failed to remove VM from Veeam Job id: {}" , vm .getBackupExternalId ());
193+ logger .warn ("Failed to remove VM from Veeam Job id: " + vm .getBackupExternalId ());
206194 }
207195 } catch (Exception e ) {
208196 logger .debug ("VM was removed from the job so could not remove again, trying to delete the veeam job now." , e );
209197 }
210198
211199 final String clonedJobName = getGuestBackupName (vm .getInstanceName (), vm .getUuid ());
212200 if (!client .deleteJobAndBackup (clonedJobName )) {
213- logger .warn ("Failed to remove Veeam job and backup for job: {}" , clonedJobName );
201+ logger .warn ("Failed to remove Veeam job and backup for job: " + clonedJobName );
214202 throw new CloudRuntimeException ("Failed to delete Veeam B&R job and backup, an operation may be in progress. Please try again after some time." );
215203 }
216204 client .syncBackupRepository ();
@@ -236,9 +224,9 @@ public boolean deleteBackup(Backup backup, boolean forced) {
236224 throw new CloudRuntimeException (String .format ("Could not find any VM associated with the Backup [uuid: %s, name: %s, externalId: %s]." , backup .getUuid (), backup .getName (), backup .getExternalId ()));
237225 }
238226 if (!forced ) {
239- logger .debug ("Veeam backup provider does not have a safe way to remove a single restore point, which results in all backup chain being removed. "
240- + "More information about this limitation can be found in the links: [{}, {} ]." , "https://forums.veeam.com/powershell-f26/removing-a-single-restorepoint-t21061.html" ,
241- "https://helpcenter.veeam.com/docs/backup/vsphere/retention_separate_vms.html?ver=110" );
227+ logger .debug (String . format ( "Veeam backup provider does not have a safe way to remove a single restore point, which results in all backup chain being removed. "
228+ + "More information about this limitation can be found in the links: [%s, %s ]." , "https://forums.veeam.com/powershell-f26/removing-a-single-restorepoint-t21061.html" ,
229+ "https://helpcenter.veeam.com/docs/backup/vsphere/retention_separate_vms.html?ver=110" )) ;
242230 throw new CloudRuntimeException ("Veeam backup provider does not have a safe way to remove a single restore point, which results in all backup chain being removed. "
243231 + "Use forced:true to skip this verification and remove the complete backup chain." );
244232 }
@@ -265,7 +253,7 @@ public boolean restoreVMFromBackup(VirtualMachine vm, Backup backup) {
265253 try {
266254 return getClient (vm .getDataCenterId ()).restoreFullVM (vm .getInstanceName (), restorePointId );
267255 } catch (Exception ex ) {
268- logger .error ("Failed to restore Full VM due to: {} . Retrying after some preparation" , ex .getMessage ());
256+ logger .error (String . format ( "Failed to restore Full VM due to: %s . Retrying after some preparation" , ex .getMessage () ));
269257 prepareForBackupRestoration (vm );
270258 return getClient (vm .getDataCenterId ()).restoreFullVM (vm .getInstanceName (), restorePointId );
271259 }
@@ -275,7 +263,7 @@ private void prepareForBackupRestoration(VirtualMachine vm) {
275263 if (!Hypervisor .HypervisorType .VMware .equals (vm .getHypervisorType ())) {
276264 return ;
277265 }
278- logger .info ("Preparing for restoring VM {}" , vm );
266+ logger .info ("Preparing for restoring VM " + vm );
279267 PrepareForBackupRestorationCommand command = new PrepareForBackupRestorationCommand (vm .getInstanceName ());
280268 Long hostId = virtualMachineManager .findClusterAndHostIdForVm (vm .getId ()).second ();
281269 if (hostId == null ) {
@@ -284,7 +272,7 @@ private void prepareForBackupRestoration(VirtualMachine vm) {
284272 try {
285273 Answer answer = agentMgr .easySend (hostId , command );
286274 if (answer != null && answer .getResult ()) {
287- logger .info ("Succeeded to prepare for restoring VM {}" , vm );
275+ logger .info ("Succeeded to prepare for restoring VM " + vm );
288276 } else {
289277 throw new CloudRuntimeException (String .format ("Failed to prepare for restoring VM %s. details: %s" , vm ,
290278 (answer != null ? answer .getDetails () : null )));
@@ -310,7 +298,7 @@ public Map<VirtualMachine, Backup.Metric> getBackupMetrics(final Long zoneId, fi
310298 }
311299
312300 List <String > vmUuids = vms .stream ().filter (Objects ::nonNull ).map (VirtualMachine ::getUuid ).collect (Collectors .toList ());
313- logger .debug ("Get Backup Metrics for VMs: [{} ]." , String .join (", " , vmUuids ));
301+ logger .debug (String . format ( "Get Backup Metrics for VMs: [%s ]." , String .join (", " , vmUuids ) ));
314302
315303 final Map <String , Backup .Metric > backendMetrics = getClient (zoneId ).getBackupMetrics ();
316304 for (final VirtualMachine vm : vms ) {
@@ -328,57 +316,22 @@ public Map<VirtualMachine, Backup.Metric> getBackupMetrics(final Long zoneId, fi
328316
329317 @ Override
330318 public Backup createNewBackupEntryForRestorePoint (Backup .RestorePoint restorePoint , VirtualMachine vm , Backup .Metric metric ) {
331- List <Backup .RestorePoint > restorePoints = listRestorePoints (vm );
332- if (CollectionUtils .isEmpty (restorePoints )) {
333- logger .debug ("Can't find any restore point to VM: {}" , vm );
334- return null ;
319+ BackupVO backup = new BackupVO ();
320+ backup .setVmId (vm .getId ());
321+ backup .setExternalId (restorePoint .getId ());
322+ backup .setType (restorePoint .getType ());
323+ backup .setDate (restorePoint .getCreated ());
324+ backup .setStatus (Backup .Status .BackedUp );
325+ if (metric != null ) {
326+ backup .setSize (metric .getBackupSize ());
327+ backup .setProtectedSize (metric .getDataSize ());
335328 }
336- final Backup [] persistedBackup = new Backup [1 ];
337- Transaction .execute (new TransactionCallbackNoReturn () {
338- @ Override
339- public void doInTransactionWithoutResult (TransactionStatus status ) {
340- final List <Backup > backupsInDb = backupDao .listByVmId (null , vm .getId ());
341- final List <Long > removeList = backupsInDb .stream ().map (InternalIdentity ::getId ).collect (Collectors .toList ());
342- for (final Backup .RestorePoint restorePoint : restorePoints ) {
343- if (!(restorePoint .getId () == null || restorePoint .getType () == null || restorePoint .getCreated () == null )) {
344- Backup existingBackupEntry = checkAndUpdateIfBackupEntryExistsForRestorePoint (backupsInDb , restorePoint , metric );
345- if (existingBackupEntry != null ) {
346- removeList .remove (existingBackupEntry .getId ());
347- continue ;
348- }
349-
350- BackupVO backup = new BackupVO ();
351- backup .setVmId (vm .getId ());
352- backup .setExternalId (restorePoint .getId ());
353- backup .setType (restorePoint .getType ());
354- backup .setDate (restorePoint .getCreated ());
355- backup .setStatus (Backup .Status .BackedUp );
356- if (metric != null ) {
357- backup .setSize (metric .getBackupSize ());
358- backup .setProtectedSize (metric .getDataSize ());
359- }
360- backup .setBackupOfferingId (vm .getBackupOfferingId ());
361- backup .setAccountId (vm .getAccountId ());
362- backup .setDomainId (vm .getDomainId ());
363- backup .setZoneId (vm .getDataCenterId ());
364- backup .setBackedUpVolumes (BackupManagerImpl .createVolumeInfoFromVolumes (volumeDao .findByInstance (vm .getId ())));
365-
366- logger .debug ("Creating a new entry in backups: [id: {}, uuid: {}, name: {}, vm_id: {}, external_id: {}, type: {}, date: {}, backup_offering_id: {}, account_id: {}, "
367- + "domain_id: {}, zone_id: {}]." , backup .getId (), backup .getUuid (), backup .getName (), backup .getVmId (), backup .getExternalId (), backup .getType (), backup .getDate (), backup .getBackupOfferingId (), backup .getAccountId (), backup .getDomainId (), backup .getZoneId ());
368- persistedBackup [0 ] = backupDao .persist (backup );
369-
370- ActionEventUtils .onCompletedActionEvent (User .UID_SYSTEM , vm .getAccountId (), EventVO .LEVEL_INFO , EventTypes .EVENT_VM_BACKUP_CREATE ,
371- String .format ("Created backup %s for VM ID: %s" , persistedBackup [0 ].getUuid (), vm .getUuid ()),
372- vm .getId (), ApiCommandResourceType .VirtualMachine .toString (),0 );
373- }
374- }
375- for (final Long backupIdToRemove : removeList ) {
376- logger .warn ("Removing backup with ID: [{}]." , backupIdToRemove );
377- backupDao .remove (backupIdToRemove );
378- }
379- }
380- });
381- return persistedBackup [0 ];
329+ backup .setBackupOfferingId (vm .getBackupOfferingId ());
330+ backup .setAccountId (vm .getAccountId ());
331+ backup .setDomainId (vm .getDomainId ());
332+ backup .setZoneId (vm .getDataCenterId ());
333+ backupDao .persist (backup );
334+ return backup ;
382335 }
383336
384337 @ Override
@@ -387,23 +340,6 @@ public List<Backup.RestorePoint> listRestorePoints(VirtualMachine vm) {
387340 return getClient (vm .getDataCenterId ()).listRestorePoints (backupName , vm .getInstanceName ());
388341 }
389342
390- private Backup checkAndUpdateIfBackupEntryExistsForRestorePoint (List <Backup > backupsInDb , Backup .RestorePoint restorePoint , Backup .Metric metric ) {
391- for (final Backup backup : backupsInDb ) {
392- if (restorePoint .getId ().equals (backup .getExternalId ())) {
393- if (metric != null ) {
394- logger .debug ("Update backup with [id: {}, uuid: {}, name: {}, external id: {}] from [size: {}, protected size: {}] to [size: {}, protected size: {}]." ,
395- backup .getId (), backup .getUuid (), backup .getName (), backup .getExternalId (), backup .getSize (), backup .getProtectedSize (), metric .getBackupSize (), metric .getDataSize ());
396-
397- ((BackupVO ) backup ).setSize (metric .getBackupSize ());
398- ((BackupVO ) backup ).setProtectedSize (metric .getDataSize ());
399- backupDao .update (backup .getId (), ((BackupVO ) backup ));
400- }
401- return backup ;
402- }
403- }
404- return null ;
405- }
406-
407343 @ Override
408344 public String getConfigComponentName () {
409345 return BackupService .class .getSimpleName ();
0 commit comments