From 5729e84dd013345f59e1445c07f3f044345c78cc Mon Sep 17 00:00:00 2001
From: Pierre Charton
Date: Fri, 13 Dec 2024 09:33:48 +0100
Subject: [PATCH] General refactoring
---
.../backup/BackrollBackupProvider.java | 151 ++---
.../backup/backroll/BackrollClient.java | 611 +++---------------
.../model/response/BackrollAsyncResponse.java | 24 +
.../BackrollBackupsFromVMResponse.java | 25 +-
.../backup/BackrollBackupResponse.java | 23 +
.../backup/BackrollBackupMetricsResponse.java | 7 +-
.../BackrollVmMetricsResponse.java | 7 +-
.../VirtualMachineBackupsResponse.java | 7 +-
.../policy/BackupPoliciesResponse.java | 6 +-
.../restore/BackrollRestoreResponse.java | 28 +
.../backroll/utils/BackrollApiException.java | 22 +
.../utils/BackrollHttpClientProvider.java | 395 +++++++++++
12 files changed, 674 insertions(+), 632 deletions(-)
create mode 100644 plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/BackrollAsyncResponse.java
create mode 100644 plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/backup/BackrollBackupResponse.java
create mode 100644 plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/restore/BackrollRestoreResponse.java
create mode 100644 plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/utils/BackrollApiException.java
create mode 100644 plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/utils/BackrollHttpClientProvider.java
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/BackrollBackupProvider.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/BackrollBackupProvider.java
index f8fd1c59c88..8feafe22c4f 100644
--- a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/BackrollBackupProvider.java
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/BackrollBackupProvider.java
@@ -34,6 +34,8 @@ import org.apache.cloudstack.backup.backroll.BackrollClient;
import org.apache.cloudstack.backup.backroll.model.BackrollBackupMetrics;
import org.apache.cloudstack.backup.backroll.model.BackrollTaskStatus;
import org.apache.cloudstack.backup.backroll.model.BackrollVmBackup;
+import org.apache.cloudstack.backup.backroll.utils.BackrollApiException;
+import org.apache.cloudstack.backup.backroll.utils.BackrollHttpClientProvider;
import org.apache.cloudstack.backup.dao.BackupDao;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
@@ -89,7 +91,6 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
@Override
public List listBackupOfferings(Long zoneId) {
logger.debug("Listing backup policies on backroll B&R Plugin");
- logger.info("Listing backup policies on backroll B&R Plugin");
BackrollClient client = getClient(zoneId);
try{
String urlToRequest = client.getBackupOfferingUrl();
@@ -105,8 +106,8 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
}
return results;
}
- } catch (KeyManagementException | ParseException | NoSuchAlgorithmException | IOException e) {
- logger.info("BackrollProvider: catch erreur!!!!!!!!!!!!!!!!!!!!!!!!");
+ } catch (ParseException | BackrollApiException | IOException e) {
+ logger.info("BackrollProvider: catch erreur: " + e);
throw new CloudRuntimeException("Failed to load backup offerings");
}
return new ArrayList();
@@ -121,8 +122,11 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
@Override
public boolean assignVMToBackupOffering(VirtualMachine vm, BackupOffering backupOffering) {
logger.info("Creating VM backup for VM {} from backup offering {}", vm.getInstanceName(), backupOffering.getName());
- ((VMInstanceVO) vm).setBackupExternalId(backupOffering.getUuid());
- return true;
+ if(vm instanceof VMInstanceVO) {
+ ((VMInstanceVO) vm).setBackupExternalId(backupOffering.getUuid());
+ return true;
+ }
+ return false;
}
@Override
@@ -131,7 +135,7 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
boolean isSuccess;
try {
isSuccess = getClient(vm.getDataCenterId()).restoreVMFromBackup(vm.getUuid(), getBackupName(backup));
- } catch (KeyManagementException | ParseException | NoSuchAlgorithmException | IOException e) {
+ } catch (ParseException | BackrollApiException | IOException e) {
throw new CloudRuntimeException("Failed to restore VM from Backrup");
}
return isSuccess;
@@ -148,6 +152,7 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
List vmUuids = vms.stream().filter(Objects::nonNull).map(VirtualMachine::getUuid).collect(Collectors.toList());
logger.debug("Get Backup Metrics for VMs: {}.", String.join(", ", vmUuids));
+ BackrollClient client = getClient(zoneId);
for (final VirtualMachine vm : vms) {
if (vm == null) {
continue;
@@ -155,8 +160,8 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
Metric metric;
try {
- metric = getClient(zoneId).getVirtualMachineMetrics(vm.getUuid());
- } catch (KeyManagementException | NoSuchAlgorithmException | IOException e) {
+ metric = client.getVirtualMachineMetrics(vm.getUuid());
+ } catch (BackrollApiException | IOException e) {
throw new CloudRuntimeException("Failed to retrieve backup metrics");
}
logger.debug("Metrics for VM [uuid: {}, name: {}] is [backup size: {}, data size: {}].", vm.getUuid(),
@@ -184,7 +189,8 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
String idBackupTask;
try {
idBackupTask = client.startBackupJob(vm.getUuid());
- } catch (KeyManagementException | NoSuchAlgorithmException | IOException e) {
+ } catch (IOException | BackrollApiException e) {
+ logger.error(e);
throw new CloudRuntimeException("Failed to take backup");
}
if (!StringUtils.isEmpty(idBackupTask)) {
@@ -210,14 +216,15 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
logger.info("Starting sync backup for VM ID " + vm.getUuid() + " on backroll provider");
final BackrollClient client = getClient(vm.getDataCenterId());
- List backupsInDb = backupDao.listByVmId(null, vm.getId());
+ List backupsInDb = backupDao.listByVmId(vm.getDataCenterId(), vm.getId());
for (Backup backup : backupsInDb) {
if (backup.getStatus().equals(Backup.Status.BackingUp)) {
BackrollTaskStatus response;
try {
response = client.checkBackupTaskStatus(backup.getExternalId());
- } catch (KeyManagementException | ParseException | NoSuchAlgorithmException | IOException e) {
+ } catch (ParseException | BackrollApiException | IOException e) {
+ logger.error(e);
throw new CloudRuntimeException("Failed to sync backups");
}
@@ -225,17 +232,7 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
logger.debug("backroll backup id: {}", backup.getExternalId());
logger.debug("backroll backup status: {}", response.getState());
- BackupVO backupToUpdate = new BackupVO();
- backupToUpdate.setVmId(backup.getVmId());
- backupToUpdate.setExternalId(backup.getExternalId());
- backupToUpdate.setType(backup.getType());
- backupToUpdate.setDate(backup.getDate());
- backupToUpdate.setSize(backup.getSize());
- backupToUpdate.setProtectedSize(backup.getProtectedSize());
- backupToUpdate.setBackupOfferingId(vm.getBackupOfferingId());
- backupToUpdate.setAccountId(backup.getAccountId());
- backupToUpdate.setDomainId(backup.getDomainId());
- backupToUpdate.setZoneId(backup.getZoneId());
+ BackupVO backupToUpdate = ((BackupVO) backup);
if (response.getState().equals("PENDING")) {
backupToUpdate.setStatus(Backup.Status.BackingUp);
@@ -248,7 +245,8 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
BackrollBackupMetrics backupMetrics = null;
try {
backupMetrics = client.getBackupMetrics(vm.getUuid() , response.getInfo());
- } catch (KeyManagementException | NoSuchAlgorithmException | IOException e) {
+ } catch (BackrollApiException | IOException e) {
+ logger.error(e);
throw new CloudRuntimeException("Failed to get backup metrics");
}
@@ -262,7 +260,6 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
if (backupDao.persist(backupToUpdate) != null) {
logger.info("Backroll mise à jour enregistrée");
- backupDao.remove(backup.getId());
}
}
} else if (backup.getStatus().equals(Backup.Status.BackedUp) && backup.getSize().equals(0L)) {
@@ -270,7 +267,8 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
BackrollBackupMetrics backupMetrics;
try {
backupMetrics = client.getBackupMetrics(vm.getUuid() , backupId);
- } catch (KeyManagementException | NoSuchAlgorithmException | IOException e) {
+ } catch (BackrollApiException | IOException e) {
+ logger.error(e);
throw new CloudRuntimeException("Failed to get backup metrics");
}
@@ -284,57 +282,63 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
}
// Backups synchronisation between Backroll ad CS Db
- List backupsFromBackroll = client.getAllBackupsfromVirtualMachine(vm.getUuid());
- backupsInDb = backupDao.listByVmId(null, vm.getId());
+ List backupsFromBackroll;
+ try {
+ backupsFromBackroll = client.getAllBackupsfromVirtualMachine(vm.getUuid());
- // insert new backroll backup in CS
- for (BackrollVmBackup backupInBackroll : backupsFromBackroll) {
- Backup backupToFind = backupsInDb.stream()
- .filter(backupInDb -> backupInDb.getExternalId().contains(backupInBackroll.getName()))
- .findAny()
- .orElse(null);
+ backupsInDb = backupDao.listByVmId(null, vm.getId());
- if (backupToFind == null) {
- BackupVO backupToInsert = new BackupVO();
- backupToInsert.setVmId(vm.getId());
- backupToInsert.setExternalId(backupInBackroll.getId() + "," + backupInBackroll.getName());
- backupToInsert.setType("INCREMENTAL");
- backupToInsert.setDate(backupInBackroll.getDate());
- backupToInsert.setSize(0L);
- backupToInsert.setProtectedSize(0L);
- backupToInsert.setStatus(Backup.Status.BackedUp);
- backupToInsert.setBackupOfferingId(vm.getBackupOfferingId());
- backupToInsert.setAccountId(vm.getAccountId());
- backupToInsert.setDomainId(vm.getDomainId());
- backupToInsert.setZoneId(vm.getDataCenterId());
- backupDao.persist(backupToInsert);
- }
- if (backupToFind != null && backupToFind.getStatus() == Backup.Status.Removed) {
- BackupVO backupToUpdate = ((BackupVO) backupToFind);
- backupToUpdate.setStatus(Backup.Status.BackedUp);
- if (backupDao.persist(backupToUpdate) != null) {
- logger.info("Backroll update saved");
- backupDao.remove(backupToFind.getId());
+ // insert new backroll backup in CS
+ for (BackrollVmBackup backupInBackroll : backupsFromBackroll) {
+ Backup backupToFind = backupsInDb.stream()
+ .filter(backupInDb -> backupInDb.getExternalId().contains(backupInBackroll.getName()))
+ .findAny()
+ .orElse(null);
+
+ if (backupToFind == null) {
+ BackupVO backupToInsert = new BackupVO();
+ backupToInsert.setVmId(vm.getId());
+ backupToInsert.setExternalId(backupInBackroll.getId() + "," + backupInBackroll.getName());
+ backupToInsert.setType("INCREMENTAL");
+ backupToInsert.setDate(backupInBackroll.getDate());
+ backupToInsert.setSize(0L);
+ backupToInsert.setProtectedSize(0L);
+ backupToInsert.setStatus(Backup.Status.BackedUp);
+ backupToInsert.setBackupOfferingId(vm.getBackupOfferingId());
+ backupToInsert.setAccountId(vm.getAccountId());
+ backupToInsert.setDomainId(vm.getDomainId());
+ backupToInsert.setZoneId(vm.getDataCenterId());
+ backupDao.persist(backupToInsert);
+ }
+ if (backupToFind != null && backupToFind.getStatus() == Backup.Status.Removed) {
+ BackupVO backupToUpdate = ((BackupVO) backupToFind);
+ backupToUpdate.setStatus(Backup.Status.BackedUp);
+ if (backupDao.persist(backupToUpdate) != null) {
+ logger.info("Backroll update saved");
+ backupDao.remove(backupToFind.getId());
+ }
}
}
- }
- // delete deleted backroll backup in CS
- backupsInDb = backupDao.listByVmId(null, vm.getId());
- for (Backup backup : backupsInDb) {
- String backupName = backup.getExternalId().contains(",") ? backup.getExternalId().split(",")[1] : backup.getExternalId();
- BackrollVmBackup backupToFind = backupsFromBackroll.stream()
- .filter(backupInBackroll -> backupInBackroll.getName().contains(backupName))
- .findAny()
- .orElse(null);
+ // delete deleted backroll backup in CS
+ backupsInDb = backupDao.listByVmId(null, vm.getId());
+ for (Backup backup : backupsInDb) {
+ String backupName = backup.getExternalId().contains(",") ? backup.getExternalId().split(",")[1] : backup.getExternalId();
+ BackrollVmBackup backupToFind = backupsFromBackroll.stream()
+ .filter(backupInBackroll -> backupInBackroll.getName().contains(backupName))
+ .findAny()
+ .orElse(null);
- if (backupToFind == null) {
- BackupVO backupToUpdate = ((BackupVO) backup);
- backupToUpdate.setStatus(Backup.Status.Removed);
- if (backupDao.persist(backupToUpdate) != null) {
- logger.debug("Backroll delete saved (sync)");
+ if (backupToFind == null) {
+ BackupVO backupToUpdate = ((BackupVO) backup);
+ backupToUpdate.setStatus(Backup.Status.Removed);
+ if (backupDao.persist(backupToUpdate) != null) {
+ logger.debug("Backroll delete saved (sync)");
+ }
}
}
+ } catch (BackrollApiException | IOException e) {
+ logger.error(e);
}
}
@@ -369,7 +373,8 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
logger.debug("Backup deletion for backup {} complete on backroll side.", backup.getUuid());
return deleteBackupInDb(backup);
}
- } catch (KeyManagementException | NoSuchAlgorithmException | IOException e) {
+ } catch (BackrollApiException | IOException e) {
+ logger.error(e);
throw new CloudRuntimeException("Failed to delete backup");
}
}
@@ -392,15 +397,17 @@ public class BackrollBackupProvider extends AdapterBase implements BackupProvide
try {
if (backrollClient == null) {
logger.debug("backroll client null - instanciation of new one ");
- backrollClient = new BackrollClient(BackrollUrlConfigKey.valueIn(zoneId), BackrollAppNameConfigKey.valueIn(zoneId), BackrollPasswordConfigKey.valueIn(zoneId), true, 300, 600);
+ BackrollHttpClientProvider provider = new BackrollHttpClientProvider(BackrollUrlConfigKey.valueIn(zoneId), BackrollAppNameConfigKey.valueIn(zoneId), BackrollPasswordConfigKey.valueIn(zoneId), true, 300, 600);
+ backrollClient = new BackrollClient(provider);
}
return backrollClient;
} catch (URISyntaxException e) {
+ logger.error(e);
throw new CloudRuntimeException("Failed to parse Backroll API URL: " + e.getMessage());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
- logger.info("Failed to build Backroll API client due to: ", e);
+ logger.error(e);
+ throw new CloudRuntimeException("Failed to build Backroll API client");
}
- throw new CloudRuntimeException("Failed to build Backroll API client");
}
private String getBackupName(Backup backup) {
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/BackrollClient.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/BackrollClient.java
index 469a354a2f2..a5978b81541 100644
--- a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/BackrollClient.java
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/BackrollClient.java
@@ -17,31 +17,19 @@
package org.apache.cloudstack.backup.backroll;
import java.io.IOException;
-import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.backup.BackupOffering;
import org.apache.cloudstack.backup.Backup.Metric;
-import org.apache.cloudstack.backup.backroll.model.BackrollBackup;
import org.apache.cloudstack.backup.backroll.model.BackrollBackupMetrics;
import org.apache.cloudstack.backup.backroll.model.BackrollOffering;
import org.apache.cloudstack.backup.backroll.model.BackrollTaskStatus;
import org.apache.cloudstack.backup.backroll.model.BackrollVmBackup;
import org.apache.cloudstack.backup.backroll.model.response.BackrollTaskRequestResponse;
import org.apache.cloudstack.backup.backroll.model.response.TaskState;
-import org.apache.cloudstack.backup.backroll.model.response.api.LoginApiResponse;
-import org.apache.cloudstack.backup.backroll.model.response.archive.BackrollArchiveResponse;
import org.apache.cloudstack.backup.backroll.model.response.archive.BackrollBackupsFromVMResponse;
import org.apache.cloudstack.backup.backroll.model.response.backup.BackrollBackupStatusResponse;
import org.apache.cloudstack.backup.backroll.model.response.backup.BackrollBackupStatusSuccessResponse;
@@ -52,28 +40,11 @@ import org.apache.cloudstack.backup.backroll.model.response.metrics.virtualMachi
import org.apache.cloudstack.backup.backroll.model.response.metrics.virtualMachineBackups.VirtualMachineBackupsResponse;
import org.apache.cloudstack.backup.backroll.model.response.policy.BackrollBackupPolicyResponse;
import org.apache.cloudstack.backup.backroll.model.response.policy.BackupPoliciesResponse;
-import org.apache.cloudstack.utils.security.SSLUtils;
+import org.apache.cloudstack.backup.backroll.utils.BackrollApiException;
+import org.apache.cloudstack.backup.backroll.utils.BackrollHttpClientProvider;
import org.apache.commons.lang3.StringUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHeaders;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.ParseException;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpDelete;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.conn.ssl.NoopHostnameVerifier;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.util.EntityUtils;
-
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -81,585 +52,177 @@ import org.joda.time.DateTime;
import org.json.JSONException;
import org.json.JSONObject;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.nio.TrustAllManager;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class BackrollClient {
private Logger logger = LogManager.getLogger(BackrollClient.class);
- private final URI apiURI;
+ private BackrollHttpClientProvider httpProvider;
- private String backrollToken = null;
- private String appname = null;
- private String password = null;
- private boolean validateCertificate = false;
- private RequestConfig config = null;
-
- private int restoreTimeout;
-
- public BackrollClient(final String url, final String appname, final String password,
- final boolean validateCertificate, final int timeout,
- final int restoreTimeout)
+ public BackrollClient(BackrollHttpClientProvider httpProvider)
throws URISyntaxException, NoSuchAlgorithmException, KeyManagementException {
- this.apiURI = new URI(url);
- this.restoreTimeout = restoreTimeout;
- this.appname = appname;
- this.password = password;
- this.config = RequestConfig.custom()
- .setConnectTimeout(timeout * 1000)
- .setConnectionRequestTimeout(timeout * 1000)
- .setSocketTimeout(timeout * 1000)
- .build();
+ this.httpProvider = httpProvider;
}
- private CloseableHttpClient createHttpClient() throws KeyManagementException, NoSuchAlgorithmException {
- if(!validateCertificate) {
- SSLContext sslContext = SSLUtils.getSSLContext();
- sslContext.init(null, new X509TrustManager[] { new TrustAllManager() }, new SecureRandom());
- final SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
- return HttpClientBuilder.create()
- .setDefaultRequestConfig(config)
- .setSSLSocketFactory(factory)
- .build();
- } else {
- return HttpClientBuilder.create()
- .setDefaultRequestConfig(config)
- .build();
- }
- }
-
- private void closeConnection(CloseableHttpResponse closeableHttpResponse) throws IOException {
- closeableHttpResponse.close();
- }
-
- public String startBackupJob(final String jobId) throws KeyManagementException, NoSuchAlgorithmException, IOException {
+ public String startBackupJob(final String jobId) throws IOException, BackrollApiException {
logger.info("Trying to start backup for Backroll job: {}", jobId);
String backupJob = "";
-
- loginIfAuthenticationFailed();
-
- try {
- CloseableHttpResponse response = post(String.format("/tasks/singlebackup/%s", jobId), null);
- String result = okBody(response);
- BackrollTaskRequestResponse requestResponse = new ObjectMapper().readValue(result, BackrollTaskRequestResponse.class);
- response.close();
- backupJob = requestResponse.location.replace("/api/v1/status/", "");
- } catch (final Exception e) {
- logger.error("Failed to start Backroll backup job due to: {}", e.getMessage());
- }
+ BackrollTaskRequestResponse requestResponse = httpProvider.post(String.format("/tasks/singlebackup/%s", jobId), null, BackrollTaskRequestResponse.class);
+ backupJob = requestResponse.location.replace("/api/v1/status/", "");
return StringUtils.isEmpty(backupJob) ? null : backupJob;
}
- public String getBackupOfferingUrl() throws KeyManagementException, NoSuchAlgorithmException, IOException {
- logger.info("Trying to list backroll backup policies");
-
- loginIfAuthenticationFailed();
+ public String getBackupOfferingUrl() throws IOException, BackrollApiException {
+ logger.info("Trying to get backroll backup policies url");
String url = "";
-
- try {
- CloseableHttpResponse response = get("/backup_policies");
- String result = okBody(response);
- logger.info("BackrollClient:getBackupOfferingUrl:result: " + result);
- //BackrollTaskRequestResponse requestResponse = parse(result);
- BackrollTaskRequestResponse requestResponse = new ObjectMapper().readValue(result, BackrollTaskRequestResponse.class);
- logger.info("BackrollClient:getBackupOfferingUrl:Apres PArse: " + requestResponse.location);
- response.close();
- url = requestResponse.location.replace("/api/v1", "");
- } catch (final Exception e) {
- logger.info("Failed to list Backroll jobs due to: {}", e.getMessage());
- logger.error("Failed to list Backroll jobs due to: {}", e.getMessage());
- }
+ BackrollTaskRequestResponse requestResponse = httpProvider.get("/backup_policies", BackrollTaskRequestResponse.class);
+ logger.info("BackrollClient:getBackupOfferingUrl:Apres Parse: " + requestResponse.location);
+ url = requestResponse.location.replace("/api/v1", "");
return StringUtils.isEmpty(url) ? null : url;
}
- public List getBackupOfferings(String idTask) throws KeyManagementException, ParseException, NoSuchAlgorithmException, IOException {
+ public List getBackupOfferings(String idTask) throws BackrollApiException, IOException {
logger.info("Trying to list backroll backup policies");
-
- loginIfAuthenticationFailed();
final List policies = new ArrayList<>();
-
- try {
- String results = waitGet(idTask);
- BackupPoliciesResponse backupPoliciesResponse = new ObjectMapper().readValue(results, BackupPoliciesResponse.class);
-
- for (final BackrollBackupPolicyResponse policy : backupPoliciesResponse.backupPolicies) {
- policies.add(new BackrollOffering(policy.name, policy.id));
- }
- } catch (final IOException | InterruptedException e) {
- logger.error("Failed to list Backroll jobs due to: {}", e.getMessage());
+ BackupPoliciesResponse backupPoliciesResponse = httpProvider.waitGet(idTask, BackupPoliciesResponse.class);
+ logger.info("BackrollClient:getBackupOfferings:Apres Parse: " + backupPoliciesResponse.backupPolicies.get(0).name);
+ for (final BackrollBackupPolicyResponse policy : backupPoliciesResponse.backupPolicies) {
+ policies.add(new BackrollOffering(policy.name, policy.id));
}
+
return policies;
}
- public boolean restoreVMFromBackup(final String vmId, final String backupName) throws KeyManagementException, ParseException, NoSuchAlgorithmException, IOException {
+ public boolean restoreVMFromBackup(final String vmId, final String backupName) throws IOException, BackrollApiException {
logger.info("Start restore backup with backroll with backup {} for vm {}", backupName, vmId);
- loginIfAuthenticationFailed();
boolean isRestoreOk = false;
+ JSONObject jsonBody = new JSONObject();
try {
- JSONObject jsonBody = new JSONObject();
- try {
- jsonBody.put("virtual_machine_id", vmId);
- jsonBody.put("backup_name", backupName);
- jsonBody.put("storage", "");
- jsonBody.put("mode", "single");
+ jsonBody.put("virtual_machine_id", vmId);
+ jsonBody.put("backup_name", backupName);
+ jsonBody.put("storage", "");
+ jsonBody.put("mode", "single");
- } catch (JSONException e) {
- logger.error("Backroll Error: {}", e.getMessage());
- }
-
- CloseableHttpResponse response = post(String.format("/tasks/restore/%s", vmId), jsonBody);
- String result = okBody(response);
- BackrollTaskRequestResponse requestResponse = new ObjectMapper().readValue(result, BackrollTaskRequestResponse.class);
- response.close();
- String urlToRequest = requestResponse.location.replace("/api/v1", "");
- result = waitGet(urlToRequest);
-
- if(result.contains("SUCCESS")) {
- logger.debug("RESTORE SUCCESS");
- isRestoreOk = true;
- }
-
- } catch (final NotOkBodyException e) {
- return false;
- } catch (final IOException | InterruptedException e) {
- logger.error("Ouch! Failed to restore VM with Backroll due to: {}", e.getMessage());
- throw new CloudRuntimeException("Ouch! Failed to restore VM with Backroll due to: {}" + e.getMessage());
+ } catch (JSONException e) {
+ logger.error("Backroll Error: {}", e.getMessage());
}
+
+ BackrollTaskRequestResponse requestResponse = httpProvider.post(String.format("/tasks/restore/%s", vmId), jsonBody, BackrollTaskRequestResponse.class);
+ String urlToRequest = requestResponse.location.replace("/api/v1", "");
+
+ String result = httpProvider.waitGetWithoutParseResponse(urlToRequest);
+ if(result.contains("SUCCESS")) {
+ logger.debug("RESTORE SUCCESS content : " + result);
+ logger.debug("RESTORE SUCCESS");
+ isRestoreOk = true;
+ }
+
return isRestoreOk;
}
- public BackrollTaskStatus checkBackupTaskStatus(String taskId) throws KeyManagementException, ParseException, NoSuchAlgorithmException, IOException {
+ public BackrollTaskStatus checkBackupTaskStatus(String taskId) throws IOException, BackrollApiException {
logger.info("Trying to get backup status for Backroll task: {}", taskId);
- loginIfAuthenticationFailed();
-
BackrollTaskStatus status = new BackrollTaskStatus();
- try {
+ String backupResponse = httpProvider.getWithoutParseResponse("/status/" + taskId);
- String body = okBody(get("/status/" + taskId));
-
- if (body.contains(TaskState.FAILURE) || body.contains(TaskState.PENDING)) {
- BackrollBackupStatusResponse backupStatusRequestResponse = new ObjectMapper().readValue(body, BackrollBackupStatusResponse.class);
- status.setState(backupStatusRequestResponse.state);
- } else {
- BackrollBackupStatusSuccessResponse backupStatusSuccessRequestResponse = new ObjectMapper().readValue(body, BackrollBackupStatusSuccessResponse.class);
- status.setState(backupStatusSuccessRequestResponse.state);
- status.setInfo(backupStatusSuccessRequestResponse.info);
- }
-
- } catch (final NotOkBodyException e) {
- // throw new CloudRuntimeException("Failed to retrieve backups status for this
- // VM via Backroll");
- logger.error("Failed to retrieve backups status for this VM via Backroll");
-
- } catch (final IOException e) {
- logger.error("Failed to check backups status due to: {}", e.getMessage());
+ if (backupResponse.contains(TaskState.FAILURE) || backupResponse.contains(TaskState.PENDING)) {
+ BackrollBackupStatusResponse backupStatusRequestResponse = new ObjectMapper().readValue(backupResponse, BackrollBackupStatusResponse.class);
+ status.setState(backupStatusRequestResponse.state);
+ } else {
+ BackrollBackupStatusSuccessResponse backupStatusSuccessRequestResponse = new ObjectMapper().readValue(backupResponse, BackrollBackupStatusSuccessResponse.class);
+ status.setState(backupStatusSuccessRequestResponse.state);
+ status.setInfo(backupStatusSuccessRequestResponse.info);
}
+
return StringUtils.isEmpty(status.getState()) ? null : status;
}
- public boolean deleteBackup(final String vmId, final String backupName) throws KeyManagementException, NoSuchAlgorithmException, IOException {
+ public boolean deleteBackup(final String vmId, final String backupName) throws IOException, BackrollApiException{
logger.info("Trying to delete backup {} for vm {} using Backroll", vmId, backupName);
-
- loginIfAuthenticationFailed();
-
boolean isBackupDeleted = false;
- try {
+ BackrollTaskRequestResponse requestResponse = httpProvider.delete(String.format("/virtualmachines/%s/backups/%s", vmId, backupName), BackrollTaskRequestResponse.class);
+ String urlToRequest = requestResponse.location.replace("/api/v1", "");
- CloseableHttpResponse response = delete(String.format("/virtualmachines/%s/backups/%s", vmId, backupName));
- String result = okBody(response);
- BackrollTaskRequestResponse requestResponse = new ObjectMapper().readValue(result, BackrollTaskRequestResponse.class);
- response.close();
- String urlToRequest = requestResponse.location.replace("/api/v1", "");
+ BackrollBackupsFromVMResponse backrollBackupsFromVMResponse = httpProvider.waitGet(urlToRequest, BackrollBackupsFromVMResponse.class);
+ logger.debug(backrollBackupsFromVMResponse.state);
+ isBackupDeleted = backrollBackupsFromVMResponse.state.equals(TaskState.SUCCESS);
- result = waitGet(urlToRequest);
- BackrollBackupsFromVMResponse backrollBackupsFromVMResponse = new ObjectMapper().readValue(result, BackrollBackupsFromVMResponse.class);
- logger.debug(backrollBackupsFromVMResponse.state);
- isBackupDeleted = backrollBackupsFromVMResponse.state.equals(TaskState.SUCCESS);
- } catch (final NotOkBodyException e) {
- isBackupDeleted = false;
- } catch (final Exception e) {
- isBackupDeleted = false;
- logger.error("Failed to delete backup using Backroll due to: {}", e.getMessage());
- }
return isBackupDeleted;
}
- public Metric getVirtualMachineMetrics(final String vmId) throws KeyManagementException, NoSuchAlgorithmException, IOException {
+ public Metric getVirtualMachineMetrics(final String vmId) throws IOException, BackrollApiException {
logger.info("Trying to retrieve virtual machine metric from Backroll for vm {}", vmId);
- loginIfAuthenticationFailed();
-
Metric metric = new Metric(0L, 0L);
- try {
+ BackrollTaskRequestResponse requestResponse = httpProvider.get(String.format("/virtualmachines/%s/repository", vmId), BackrollTaskRequestResponse.class);
- CloseableHttpResponse response = get(String.format("/virtualmachines/%s/repository", vmId));
- String result = okBody(response);
- BackrollTaskRequestResponse requestResponse = new ObjectMapper().readValue(result, BackrollTaskRequestResponse.class);
- response.close();
- String urlToRequest = requestResponse.location.replace("/api/v1", "");
+ String urlToRequest = requestResponse.location.replace("/api/v1", "");
- result = waitGet(urlToRequest);
- BackrollVmMetricsResponse vmMetricsResponse =new ObjectMapper().readValue(result, BackrollVmMetricsResponse.class);
+ BackrollVmMetricsResponse vmMetricsResponse = httpProvider.waitGet(urlToRequest, BackrollVmMetricsResponse.class);
- if (vmMetricsResponse != null && vmMetricsResponse.state.equals(TaskState.SUCCESS)) {
- logger.debug("SUCCESS ok");
- CacheStats stats = null;
- try {
- stats = vmMetricsResponse.infos.cache.stats;
- } catch (NullPointerException e) {
- }
- if (stats != null) {
- long size = Long.parseLong(stats.totalSize);
- metric = new Metric(size, size);
- }
+ if (vmMetricsResponse != null && vmMetricsResponse.state.equals(TaskState.SUCCESS)) {
+ logger.debug("SUCCESS ok");
+ CacheStats stats = null;
+ try {
+ stats = vmMetricsResponse.infos.cache.stats;
+ } catch (NullPointerException e) {
+ }
+ if (stats != null) {
+ long size = Long.parseLong(stats.totalSize);
+ metric = new Metric(size, size);
}
- } catch (final Exception e) {
- logger.error("Failed to retrieve virtual machine metrics with Backroll due to: {}", e.getMessage());
}
return metric;
}
- public BackrollBackupMetrics getBackupMetrics(String vmId, String backupId) throws KeyManagementException, NoSuchAlgorithmException, IOException {
+ public BackrollBackupMetrics getBackupMetrics(String vmId, String backupId) throws IOException, BackrollApiException {
logger.info("Trying to get backup metrics for VM: {}, and backup: {}", vmId, backupId);
- loginIfAuthenticationFailed();
-
BackrollBackupMetrics metrics = null;
- try {
+ BackrollTaskRequestResponse requestResponse = httpProvider.get(String.format("/virtualmachines/%s/backups/%s", vmId, backupId), BackrollTaskRequestResponse.class);
- CloseableHttpResponse response = get(String.format("/virtualmachines/%s/backups/%s", vmId, backupId));
- String result = okBody(response);
- BackrollTaskRequestResponse requestResponse = new ObjectMapper().readValue(result, BackrollTaskRequestResponse.class);
- response.close();
- String urlToRequest = requestResponse.location.replace("/api/v1", "");
+ String urlToRequest = requestResponse.location.replace("/api/v1", "");
- logger.debug(urlToRequest);
+ logger.debug(urlToRequest);
- result = waitGet(urlToRequest);
- BackrollBackupMetricsResponse metricsResponse = new ObjectMapper().readValue(result, BackrollBackupMetricsResponse.class);
- if (metricsResponse.info != null) {
- metrics = new BackrollBackupMetrics(Long.parseLong(metricsResponse.info.originalSize),
- Long.parseLong(metricsResponse.info.deduplicatedSize));
- }
- } catch (final NotOkBodyException e) {
- throw new CloudRuntimeException("Failed to retrieve backups status for this VM via Backroll");
- } catch (final IOException | InterruptedException e) {
- logger.error("Failed to check backups status due to: {}", e.getMessage());
+ BackrollBackupMetricsResponse metricsResponse = httpProvider.waitGet(urlToRequest, BackrollBackupMetricsResponse.class);
+ if (metricsResponse.info != null) {
+ metrics = new BackrollBackupMetrics(Long.parseLong(metricsResponse.info.originalSize),
+ Long.parseLong(metricsResponse.info.deduplicatedSize));
}
return metrics;
}
- public List getAllBackupsfromVirtualMachine(String vmId) {
+ public List getAllBackupsfromVirtualMachine(String vmId) throws BackrollApiException, IOException {
logger.info("Trying to retrieve all backups for vm {}", vmId);
List backups = new ArrayList();
- try {
+ BackrollTaskRequestResponse requestResponse = httpProvider.get(String.format("/virtualmachines/%s/backups", vmId), BackrollTaskRequestResponse.class);
- CloseableHttpResponse response = get(String.format("/virtualmachines/%s/backups", vmId));
- String result = okBody(response);
- BackrollTaskRequestResponse requestResponse = new ObjectMapper().readValue(result, BackrollTaskRequestResponse.class);
- response.close();
- String urlToRequest = requestResponse.location.replace("/api/v1", "");
+ String urlToRequest = requestResponse.location.replace("/api/v1", "");
+ logger.debug(urlToRequest);
+ VirtualMachineBackupsResponse virtualMachineBackupsResponse = httpProvider.waitGet(urlToRequest, VirtualMachineBackupsResponse.class);
- logger.debug(urlToRequest);
-
- result = waitGet(urlToRequest);
- VirtualMachineBackupsResponse virtualMachineBackupsResponse = new ObjectMapper().readValue(result, VirtualMachineBackupsResponse.class);
-
- if (virtualMachineBackupsResponse.state.equals(TaskState.SUCCESS)) {
- if (virtualMachineBackupsResponse.info.archives.size() > 0) {
- for (BackupInfos infos : virtualMachineBackupsResponse.info.archives) {
- var dateStart = new DateTime(infos.start);
- backups.add(new BackrollVmBackup(infos.id, infos.name, dateStart.toDate()));
- }
+ if (virtualMachineBackupsResponse.state.equals(TaskState.SUCCESS)) {
+ if (virtualMachineBackupsResponse.info.archives.size() > 0) {
+ for (BackupInfos infos : virtualMachineBackupsResponse.info.archives) {
+ var dateStart = new DateTime(infos.start);
+ backups.add(new BackrollVmBackup(infos.id, infos.name, dateStart.toDate()));
}
}
-
- } catch (Exception e) {
- e.printStackTrace();
}
+
return backups;
}
-
- private CloseableHttpResponse post(final String path, final JSONObject json) throws IOException, KeyManagementException, NoSuchAlgorithmException {
- CloseableHttpClient httpClient = createHttpClient();
-
- String xml = null;
- StringEntity params = null;
- if (json != null) {
- logger.debug("JSON {}", json.toString());
- params = new StringEntity(json.toString(), ContentType.APPLICATION_JSON);
- }
-
- String url = apiURI.toString() + path;
- final HttpPost request = new HttpPost(url);
-
- if (params != null) {
- request.setEntity(params);
- }
-
- request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + backrollToken);
- request.setHeader("Content-type", "application/json");
-
- final CloseableHttpResponse response = httpClient.execute(request);
-
- logger.debug("Response received in POST request with body {} is: {} for URL {}.", xml, response.toString(), url);
-
- return response;
- }
-
- protected CloseableHttpResponse get(String path) throws IOException, KeyManagementException, NoSuchAlgorithmException {
- CloseableHttpClient httpClient = createHttpClient();
-
- String url = apiURI.toString() + path;
- logger.debug("Backroll URL {}", url);
-
- HttpGet request = new HttpGet(url);
- request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + backrollToken);
- request.setHeader("Content-type", "application/json");
- CloseableHttpResponse response = httpClient.execute(request);
- logger.debug("Response received in GET request is: {} for URL: {}.", response.toString(), url);
- return response;
- }
-
- protected CloseableHttpResponse delete(String path) throws IOException, KeyManagementException, NoSuchAlgorithmException {
- CloseableHttpClient httpClient = createHttpClient();
-
- String url = apiURI.toString() + path;
- final HttpDelete request = new HttpDelete(url);
- request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + backrollToken);
- request.setHeader("Content-type", "application/json");
- final CloseableHttpResponse response = httpClient.execute(request);
- logger.debug("Response received in GET request is: {} for URL: {}.", response.toString(), url);
- return response;
- }
-
- private boolean isResponseAuthorized(final HttpResponse response) {
- return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK
- || response.getStatusLine().getStatusCode() == HttpStatus.SC_ACCEPTED;
- }
-
- private class NotOkBodyException extends Exception {
- }
-
- private String okBody(final CloseableHttpResponse response)
- throws ParseException, IOException, NotOkBodyException {
- String result = "";
- switch (response.getStatusLine().getStatusCode()) {
- case HttpStatus.SC_OK:
- case HttpStatus.SC_ACCEPTED:
- HttpEntity bodyEntity = response.getEntity();
- try {
- result = EntityUtils.toString(bodyEntity);
- EntityUtils.consumeQuietly(bodyEntity);
- closeConnection(response);
- return result;
- } finally {
- EntityUtils.consumeQuietly(bodyEntity);
- }
- default:
- closeConnection(response);
- throw new NotOkBodyException();
- }
- }
-
- private T parse(final String json)
- throws JsonMappingException, JsonProcessingException {
- return new ObjectMapper().readValue(json, new TypeReference() {
- });
- }
-
- private String waitGet(String url)
- throws IOException, InterruptedException, KeyManagementException, ParseException, NoSuchAlgorithmException {
- // int threshold = 30; // 5 minutes
- int maxAttempts = 12; // 2 minutes
-
- for (int attempt = 1; attempt <= maxAttempts; attempt++) {
- try {
- String body = okBody(get(url));
- if (!body.contains(TaskState.PENDING)) {
- return body;
- }
- } catch (final NotOkBodyException e) {
- throw new CloudRuntimeException("An error occured with Backroll");
- }
- TimeUnit.SECONDS.sleep(10);
- }
-
- return null;
- }
-
- private boolean isAuthenticated() throws KeyManagementException, NoSuchAlgorithmException {
- boolean result = false;
-
- if(StringUtils.isEmpty(backrollToken)) {
- return result;
- }
-
- try {
- CloseableHttpResponse response = post("/auth", null);
- result = isResponseAuthorized(response);
- EntityUtils.consumeQuietly(response.getEntity());
- closeConnection(response);
- } catch (IOException e) {
- logger.error("Failed to authenticate to Backroll due to: {}", e.getMessage());
- }
- return result;
- }
-
- private void loginIfAuthenticationFailed() throws KeyManagementException, NoSuchAlgorithmException, IOException {
- if (!isAuthenticated()) {
- login(appname, password);
- }
- }
-
- // private void login(final String appname, final String appsecret) throws IOException, KeyManagementException, NoSuchAlgorithmException {
- // logger.info("Backroll client - start login");
- // CloseableHttpClient httpClient = createHttpClient();
- // CloseableHttpResponse response = null;
- // final HttpPost request = new HttpPost(apiURI.toString() + "/login");
- // request.addHeader("content-type", "application/json");
-
- // JSONObject jsonBody = new JSONObject();
- // StringEntity params;
-
- // try {
- // jsonBody.put("app_id", appname);
- // jsonBody.put("app_secret", appsecret);
- // params = new StringEntity(jsonBody.toString());
- // request.setEntity(params);
-
- // response = httpClient.execute(request);
-
- // try {
- // HttpEntity body = response.getEntity();
- // String bodyStr = EntityUtils.toString(body);
-
- // LoginApiResponse loginResponse = new ObjectMapper().readValue(bodyStr, LoginApiResponse.class);
- // backrollToken = loginResponse.accessToken;
- // logger.debug(String.format("Backroll client - Token : %s", backrollToken));
-
- // EntityUtils.consumeQuietly(response.getEntity());
-
- // if (StringUtils.isEmpty(loginResponse.accessToken)) {
- // throw new CloudRuntimeException("Backroll token is not available to perform API requests");
- // }
- // } catch (final Exception e) {
- // EntityUtils.consumeQuietly(response.getEntity());
- // if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
- // throw new CloudRuntimeException(
- // "Failed to create and authenticate Backroll client, please check the settings.");
- // } else {
- // throw new ServerApiException(ApiErrorCode.UNAUTHORIZED,
- // "Backroll API call unauthorized, please ask your administrator to fix integration issues.");
- // }
- // }
-
- // } catch (final IOException e) {
- // throw new CloudRuntimeException("Failed to authenticate Backroll API service due to:" + e.getMessage());
- // } catch (JSONException e) {
- // e.printStackTrace();
- // }
- // finally {
- // closeConnection(response);
- // }
- // logger.info("Backroll client - end login");
- // }
-
- private void login(final String appname, final String appsecret) throws IOException, KeyManagementException, NoSuchAlgorithmException {
- logger.debug("Backroll client - start login");
-
- CloseableHttpClient httpClient = createHttpClient();
- CloseableHttpResponse response = null;
-
- final HttpPost request = new HttpPost(apiURI.toString() + "/login");
- request.addHeader("content-type", "application/json");
-
- JSONObject jsonBody = new JSONObject();
- StringEntity params;
-
- try {
- jsonBody.put("app_id", appname);
- jsonBody.put("app_secret", appsecret);
- params = new StringEntity(jsonBody.toString());
- request.setEntity(params);
-
- response = httpClient.execute(request);
- try {
- String toto = okBody(response);
- ObjectMapper objectMapper = new ObjectMapper();
- logger.info("BACKROLL: " + toto);
- LoginApiResponse loginResponse = objectMapper.readValue(toto, LoginApiResponse.class);
- logger.info("ok");
- backrollToken = loginResponse.accessToken;
- logger.debug("Backroll client - Token : {}", backrollToken);
-
- if (StringUtils.isEmpty(loginResponse.accessToken)) {
- throw new CloudRuntimeException("Backroll token is not available to perform API requests");
- }
- } catch (final NotOkBodyException e) {
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
- throw new CloudRuntimeException(
- "Failed to create and authenticate Backroll client, please check the settings.");
- } else {
- throw new ServerApiException(ApiErrorCode.UNAUTHORIZED,
- "Backroll API call unauthorized, please ask your administrator to fix integration issues.");
- }
- }
- } catch (final IOException e) {
- throw new CloudRuntimeException("Failed to authenticate Backroll API service due to:" + e.getMessage());
- } catch (JSONException e) {
- e.printStackTrace();
- }
- finally {
- closeConnection(response);
- }
- logger.debug("Backroll client - end login");
- }
-
- private List getBackrollBackups(final String vmId) throws KeyManagementException, ParseException, NoSuchAlgorithmException {
- try {
- logger.info("start to list Backroll backups for vm {}", vmId);
-
- CloseableHttpResponse response = get("/virtualmachines/" + vmId + "/backups");
- String result = okBody(response);
- BackrollTaskRequestResponse requestResponse = new ObjectMapper().readValue(result, BackrollTaskRequestResponse.class);
- response.close();
- String urlToRequest = requestResponse.location.replace("/api/v1", "");
-
- logger.debug(urlToRequest);
- result = waitGet(urlToRequest);
- BackrollBackupsFromVMResponse backrollBackupsFromVMResponse = new ObjectMapper().readValue(result, BackrollBackupsFromVMResponse.class);
-
- final List backups = new ArrayList<>();
- for (final BackrollArchiveResponse archive : backrollBackupsFromVMResponse.archives.archives) {
- backups.add(new BackrollBackup(archive.name));
- logger.debug(archive.name);
- }
- return backups;
- } catch (final NotOkBodyException e) {
- throw new CloudRuntimeException("Failed to retrieve backups for this VM via Backroll");
- } catch (final IOException e) {
- logger.error("Failed to list backup form vm with Backroll due to: {}", e);
- } catch (InterruptedException e) {
- logger.error("Backroll Error: {}", e);
- }
- return new ArrayList();
- }
}
\ No newline at end of file
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/BackrollAsyncResponse.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/BackrollAsyncResponse.java
new file mode 100644
index 00000000000..84c94b5fbbc
--- /dev/null
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/BackrollAsyncResponse.java
@@ -0,0 +1,24 @@
+// 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
+// with 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.backroll.model.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public abstract class BackrollAsyncResponse {
+ @JsonProperty("state")
+ public String state;
+}
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/archive/BackrollBackupsFromVMResponse.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/archive/BackrollBackupsFromVMResponse.java
index 6e066dce7f6..0fa3398bda8 100644
--- a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/archive/BackrollBackupsFromVMResponse.java
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/archive/BackrollBackupsFromVMResponse.java
@@ -1,27 +1,10 @@
-// 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
-// with 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.backroll.model.response.archive;
+import org.apache.cloudstack.backup.backroll.model.response.BackrollAsyncResponse;
+
import com.fasterxml.jackson.annotation.JsonProperty;
-public class BackrollBackupsFromVMResponse {
- @JsonProperty("state")
- public String state;
-
+public class BackrollBackupsFromVMResponse extends BackrollAsyncResponse {
@JsonProperty("info")
public BackrollArchivesResponse archives;
-}
+}
\ No newline at end of file
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/backup/BackrollBackupResponse.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/backup/BackrollBackupResponse.java
new file mode 100644
index 00000000000..a8eb0b14f58
--- /dev/null
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/backup/BackrollBackupResponse.java
@@ -0,0 +1,23 @@
+// 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
+// with 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.backroll.model.response.backup;
+
+import org.apache.cloudstack.backup.backroll.model.response.BackrollAsyncResponse;
+
+public class BackrollBackupResponse extends BackrollAsyncResponse{
+
+}
\ No newline at end of file
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/backup/BackrollBackupMetricsResponse.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/backup/BackrollBackupMetricsResponse.java
index f696ac5f20a..1582c0133f2 100644
--- a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/backup/BackrollBackupMetricsResponse.java
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/backup/BackrollBackupMetricsResponse.java
@@ -16,12 +16,11 @@
// under the License.
package org.apache.cloudstack.backup.backroll.model.response.metrics.backup;
+import org.apache.cloudstack.backup.backroll.model.response.BackrollAsyncResponse;
+
import com.fasterxml.jackson.annotation.JsonProperty;
-public class BackrollBackupMetricsResponse {
- @JsonProperty("state")
- public String state;
-
+public class BackrollBackupMetricsResponse extends BackrollAsyncResponse {
@JsonProperty("info")
public BackupMetricsInfo info;
}
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/virtualMachine/BackrollVmMetricsResponse.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/virtualMachine/BackrollVmMetricsResponse.java
index 2a9fd490e7d..74bbca646ae 100644
--- a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/virtualMachine/BackrollVmMetricsResponse.java
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/virtualMachine/BackrollVmMetricsResponse.java
@@ -16,12 +16,11 @@
// under the License.
package org.apache.cloudstack.backup.backroll.model.response.metrics.virtualMachine;
+import org.apache.cloudstack.backup.backroll.model.response.BackrollAsyncResponse;
+
import com.fasterxml.jackson.annotation.JsonProperty;
-public class BackrollVmMetricsResponse {
- @JsonProperty("state")
- public String state;
-
+public class BackrollVmMetricsResponse extends BackrollAsyncResponse{
@JsonProperty("info")
public MetricsInfos infos;
}
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/virtualMachineBackups/VirtualMachineBackupsResponse.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/virtualMachineBackups/VirtualMachineBackupsResponse.java
index 5f70a91466c..11ed8267be6 100644
--- a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/virtualMachineBackups/VirtualMachineBackupsResponse.java
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/metrics/virtualMachineBackups/VirtualMachineBackupsResponse.java
@@ -16,12 +16,11 @@
// under the License.
package org.apache.cloudstack.backup.backroll.model.response.metrics.virtualMachineBackups;
+import org.apache.cloudstack.backup.backroll.model.response.BackrollAsyncResponse;
+
import com.fasterxml.jackson.annotation.JsonProperty;
-public class VirtualMachineBackupsResponse {
- @JsonProperty("state")
- public String state;
-
+public class VirtualMachineBackupsResponse extends BackrollAsyncResponse {
@JsonProperty("info")
public Archives info;
}
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/policy/BackupPoliciesResponse.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/policy/BackupPoliciesResponse.java
index a125144b96d..f9512520386 100644
--- a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/policy/BackupPoliciesResponse.java
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/policy/BackupPoliciesResponse.java
@@ -18,12 +18,12 @@ package org.apache.cloudstack.backup.backroll.model.response.policy;
import java.util.List;
+import org.apache.cloudstack.backup.backroll.model.response.BackrollAsyncResponse;
+
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
-public class BackupPoliciesResponse {
- @JsonProperty("state")
- public String state;
+public class BackupPoliciesResponse extends BackrollAsyncResponse {
@JsonProperty("info")
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/restore/BackrollRestoreResponse.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/restore/BackrollRestoreResponse.java
new file mode 100644
index 00000000000..8f831f49e2f
--- /dev/null
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/response/restore/BackrollRestoreResponse.java
@@ -0,0 +1,28 @@
+// 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
+// with 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.backroll.model.response.restore;
+
+import org.apache.cloudstack.backup.backroll.model.response.BackrollAsyncResponse;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class BackrollRestoreResponse extends BackrollAsyncResponse {
+ @JsonProperty("info")
+ public String info;
+}
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/utils/BackrollApiException.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/utils/BackrollApiException.java
new file mode 100644
index 00000000000..a07f9e9863d
--- /dev/null
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/utils/BackrollApiException.java
@@ -0,0 +1,22 @@
+// 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
+// with 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.backroll.utils;
+
+
+public class BackrollApiException extends Exception {
+
+}
diff --git a/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/utils/BackrollHttpClientProvider.java b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/utils/BackrollHttpClientProvider.java
new file mode 100644
index 00000000000..823e7ffb972
--- /dev/null
+++ b/plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/utils/BackrollHttpClientProvider.java
@@ -0,0 +1,395 @@
+// 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
+// with 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.backroll.utils;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.concurrent.TimeUnit;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.backup.backroll.BackrollClient;
+import org.apache.cloudstack.backup.backroll.model.response.TaskState;
+import org.apache.cloudstack.backup.backroll.model.response.api.LoginApiResponse;
+import org.apache.cloudstack.utils.security.SSLUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpStatus;
+import org.apache.http.ParseException;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.nio.TrustAllManager;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class BackrollHttpClientProvider {
+ private final URI apiURI;
+ private String backrollToken = null;
+ private String appname = null;
+ private String password = null;
+ private RequestConfig config = null;
+ private boolean validateCertificate = false;
+
+ private Logger logger = LogManager.getLogger(BackrollClient.class);
+
+ public BackrollHttpClientProvider(final String url, final String appname, final String password,
+ final boolean validateCertificate, final int timeout,
+ final int restoreTimeout)
+ throws URISyntaxException, NoSuchAlgorithmException, KeyManagementException {
+ this.apiURI = new URI(url);
+ this.appname = appname;
+ this.password = password;
+ this.validateCertificate = validateCertificate;
+
+ this.config = RequestConfig.custom()
+ .setConnectTimeout(timeout * 1000)
+ .setConnectionRequestTimeout(timeout * 1000)
+ .setSocketTimeout(timeout * 1000)
+ .build();
+ }
+
+ private CloseableHttpClient createHttpClient() throws BackrollApiException {
+ if(!validateCertificate) {
+ SSLContext sslContext;
+ try {
+ sslContext = SSLUtils.getSSLContext();
+ sslContext.init(null, new X509TrustManager[] { new TrustAllManager() }, new SecureRandom());
+ final SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
+ return HttpClientBuilder.create()
+ .setDefaultRequestConfig(config)
+ .setSSLSocketFactory(factory)
+ .build();
+ } catch (NoSuchAlgorithmException | KeyManagementException e) {
+ logger.error(e);
+ e.printStackTrace();
+ throw new BackrollApiException();
+ }
+ } else {
+ return HttpClientBuilder.create()
+ .setDefaultRequestConfig(config)
+ .build();
+ }
+ }
+
+ public T post(final String path, final JSONObject json, Class classOfT) throws BackrollApiException, IOException {
+
+ loginIfAuthenticationFailed();
+
+ try (CloseableHttpClient httpClient = createHttpClient()) {
+
+ String xml = null;
+ StringEntity params = null;
+ if (json != null) {
+ logger.debug("JSON {}", json.toString());
+ params = new StringEntity(json.toString(), ContentType.APPLICATION_JSON);
+ }
+
+ String url = apiURI.toString() + path;
+ final HttpPost request = new HttpPost(url);
+
+ if (params != null) {
+ request.setEntity(params);
+ }
+
+ request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + backrollToken);
+ request.setHeader("Content-type", "application/json");
+
+ final CloseableHttpResponse response = httpClient.execute(request);
+
+ logger.debug("Response received in POST request with body {} is: {} for URL {}.", xml, response.toString(), url);
+
+ String result = okBody(response);
+ T requestResponse = new ObjectMapper().readValue(result, classOfT);
+ response.close();
+
+ return requestResponse;
+ } catch (ParseException | NotOkBodyException e) {
+ logger.error(e);
+ e.printStackTrace();
+ throw new BackrollApiException();
+ }
+ }
+
+ public T get(String path, Class classOfT) throws IOException, BackrollApiException{
+ logger.debug("Backroll Get Auth ");
+ loginIfAuthenticationFailed();
+ logger.debug("Backroll Get Auth ok");
+ try (CloseableHttpClient httpClient = createHttpClient()) {
+
+ String url = apiURI.toString() + path;
+ logger.debug("Backroll URL {}", url);
+
+ HttpGet request = new HttpGet(url);
+ request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + backrollToken);
+ request.setHeader("Content-type", "application/json");
+ CloseableHttpResponse response = httpClient.execute(request);
+ logger.debug("Response received in GET request is: {} for URL: {}.", response.toString(), url);
+
+ String result = okBody(response);
+ T requestResponse = new ObjectMapper().readValue(result, classOfT);
+ response.close();
+
+ return requestResponse;
+ } catch (NotOkBodyException e) {
+ logger.error(e);
+ e.printStackTrace();
+ throw new BackrollApiException();
+ }
+ }
+
+ public String getWithoutParseResponse(String path) throws IOException, BackrollApiException{
+ logger.debug("Backroll Get Auth ");
+ loginIfAuthenticationFailed();
+ logger.debug("Backroll Get Auth ok");
+ try (CloseableHttpClient httpClient = createHttpClient()) {
+
+ String url = apiURI.toString() + path;
+ logger.debug("Backroll URL {}", url);
+
+ HttpGet request = new HttpGet(url);
+ request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + backrollToken);
+ request.setHeader("Content-type", "application/json");
+ CloseableHttpResponse response = httpClient.execute(request);
+ logger.debug("Response received in GET request is: {} for URL: {}.", response.toString(), url);
+
+ String result = okBody(response);
+ response.close();
+
+ return result;
+ } catch (NotOkBodyException e) {
+ logger.error(e);
+ e.printStackTrace();
+ throw new BackrollApiException();
+ }
+ }
+
+ public T delete(String path, Class classOfT) throws IOException, BackrollApiException {
+
+ loginIfAuthenticationFailed();
+
+ try (CloseableHttpClient httpClient = createHttpClient()) {
+
+ String url = apiURI.toString() + path;
+ final HttpDelete request = new HttpDelete(url);
+ request.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + backrollToken);
+ request.setHeader("Content-type", "application/json");
+ final CloseableHttpResponse response = httpClient.execute(request);
+ logger.debug("Response received in GET request is: {} for URL: {}.", response.toString(), url);
+
+ String result = okBody(response);
+ T requestResponse = new ObjectMapper().readValue(result, classOfT);
+ response.close();
+
+ return requestResponse;
+ } catch (NotOkBodyException e) {
+ logger.error(e);
+ e.printStackTrace();
+ throw new BackrollApiException();
+ }
+ }
+
+ public class NotOkBodyException extends Exception {
+ }
+
+ public String okBody(final CloseableHttpResponse response) throws NotOkBodyException {
+ String result = "";
+ switch (response.getStatusLine().getStatusCode()) {
+ case HttpStatus.SC_OK:
+ case HttpStatus.SC_ACCEPTED:
+ HttpEntity bodyEntity = response.getEntity();
+ try {
+ result = EntityUtils.toString(bodyEntity);
+ EntityUtils.consumeQuietly(bodyEntity);
+ return result;
+ } catch (ParseException | IOException e) {
+ e.printStackTrace();
+ throw new NotOkBodyException();
+ } finally {
+ EntityUtils.consumeQuietly(bodyEntity);
+ }
+ default:
+ try {
+ closeConnection(response);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ throw new NotOkBodyException();
+ }
+ }
+
+ public T waitGet(String url, Class classOfT) throws IOException, BackrollApiException {
+ loginIfAuthenticationFailed();
+
+ // int threshold = 30; // 5 minutes
+ int maxAttempts = 12; // 2 minutes
+
+ for (int attempt = 1; attempt <= maxAttempts; attempt++) {
+ String body = getWithoutParseResponse(url);
+ if(!StringUtils.isEmpty(body)){
+ if (!body.contains(TaskState.PENDING)) {
+ T result = new ObjectMapper().readValue(body, classOfT);
+ return result;
+ }
+ }
+
+ try {
+ TimeUnit.SECONDS.sleep(10);
+ } catch (InterruptedException e) {
+ logger.error(e);
+ e.printStackTrace();
+ throw new BackrollApiException();
+ }
+ }
+
+ return null;
+ }
+
+ public String waitGetWithoutParseResponse(String url)
+ throws IOException, BackrollApiException {
+ // int threshold = 30; // 5 minutes
+ int maxAttempts = 12; // 2 minutes
+
+ for (int attempt = 1; attempt <= maxAttempts; attempt++) {
+
+ String body = getWithoutParseResponse(url);
+ if (!body.contains(TaskState.PENDING)) {
+ return body;
+ }
+
+ try {
+ TimeUnit.SECONDS.sleep(10);
+ } catch (InterruptedException e) {
+ logger.error(e);
+ e.printStackTrace();
+ throw new BackrollApiException();
+ }
+ }
+
+ return null;
+ }
+
+ private boolean isAuthenticated() throws BackrollApiException, IOException {
+ boolean result = false;
+
+ if(StringUtils.isEmpty(backrollToken)) {
+ logger.debug("Backroll Tocken empty : " + backrollToken);
+ return result;
+ }
+
+ try (CloseableHttpClient httpClient = createHttpClient()) {
+ final HttpPost request = new HttpPost(apiURI.toString() + "/auth");
+ CloseableHttpResponse httpResponse = httpClient.execute(request);
+ logger.debug("Backroll Auth response : " + EntityUtils.toString(httpResponse.getEntity()));
+ logger.debug("Backroll Auth response status : " + httpResponse.getStatusLine().getStatusCode());
+ String response = okBody(httpResponse);
+ logger.debug("Backroll Auth response 2 : " + response);
+ logger.debug("Backroll Auth ok");
+ result = true;
+ }catch (NotOkBodyException e) {
+ logger.error(e);
+ e.printStackTrace();
+ result = false;
+ }
+ return result;
+ }
+
+ private void closeConnection(CloseableHttpResponse closeableHttpResponse) throws IOException {
+ closeableHttpResponse.close();
+ }
+
+ public void loginIfAuthenticationFailed() throws BackrollApiException, IOException {
+ if (!isAuthenticated()) {
+ login(appname, password);
+ }
+ }
+
+ private void login(final String appname, final String appsecret) throws BackrollApiException, IOException {
+ logger.debug("Backroll client - start login");
+
+ CloseableHttpClient httpClient = createHttpClient();
+ CloseableHttpResponse httpResponse = null;
+
+ final HttpPost request = new HttpPost(apiURI.toString() + "/login");
+ request.addHeader("content-type", "application/json");
+
+ JSONObject jsonBody = new JSONObject();
+ StringEntity params;
+
+ try {
+ jsonBody.put("app_id", appname);
+ jsonBody.put("app_secret", appsecret);
+ params = new StringEntity(jsonBody.toString());
+ request.setEntity(params);
+
+ httpResponse = httpClient.execute(request);
+ try {
+ String response = okBody(httpResponse);
+ ObjectMapper objectMapper = new ObjectMapper();
+ logger.info("BACKROLL: " + response);
+ LoginApiResponse loginResponse = objectMapper.readValue(response, LoginApiResponse.class);
+ logger.info("ok");
+ this.backrollToken = loginResponse.accessToken;
+ logger.debug("Backroll client - Token : {}", backrollToken);
+
+ if (StringUtils.isEmpty(loginResponse.accessToken)) {
+ throw new CloudRuntimeException("Backroll token is not available to perform API requests");
+ }
+ } catch (final NotOkBodyException e) {
+ logger.error(e);
+ if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
+ throw new CloudRuntimeException("Failed to create and authenticate Backroll client, please check the settings.");
+ } else {
+ throw new ServerApiException(ApiErrorCode.UNAUTHORIZED, "Backroll API call unauthorized, please ask your administrator to fix integration issues.");
+ }
+ }
+ } catch (final IOException e) {
+ logger.error(e);
+ throw new CloudRuntimeException("Failed to authenticate Backroll API service due to:" + e.getMessage());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ logger.error(e);
+ throw new CloudRuntimeException("Failed to authenticate Backroll API service due to:" + e.getMessage());
+ }
+ finally {
+ closeConnection(httpResponse);
+ }
+ logger.debug("Backroll client - end login");
+ }
+}