mirror of https://github.com/apache/cloudstack.git
General refactoring
This commit is contained in:
parent
bd0bc0f39d
commit
5729e84dd0
|
|
@ -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<BackupOffering> 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<BackupOffering>();
|
||||
|
|
@ -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<String> 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<Backup> backupsInDb = backupDao.listByVmId(null, vm.getId());
|
||||
List<Backup> 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<BackrollVmBackup> backupsFromBackroll = client.getAllBackupsfromVirtualMachine(vm.getUuid());
|
||||
backupsInDb = backupDao.listByVmId(null, vm.getId());
|
||||
List<BackrollVmBackup> 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) {
|
||||
|
|
|
|||
|
|
@ -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<BackupOffering> getBackupOfferings(String idTask) throws KeyManagementException, ParseException, NoSuchAlgorithmException, IOException {
|
||||
public List<BackupOffering> getBackupOfferings(String idTask) throws BackrollApiException, IOException {
|
||||
logger.info("Trying to list backroll backup policies");
|
||||
|
||||
loginIfAuthenticationFailed();
|
||||
final List<BackupOffering> 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<BackrollVmBackup> getAllBackupsfromVirtualMachine(String vmId) {
|
||||
public List<BackrollVmBackup> getAllBackupsfromVirtualMachine(String vmId) throws BackrollApiException, IOException {
|
||||
logger.info("Trying to retrieve all backups for vm {}", vmId);
|
||||
|
||||
List<BackrollVmBackup> backups = new ArrayList<BackrollVmBackup>();
|
||||
|
||||
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> T parse(final String json)
|
||||
throws JsonMappingException, JsonProcessingException {
|
||||
return new ObjectMapper().readValue(json, new TypeReference<T>() {
|
||||
});
|
||||
}
|
||||
|
||||
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<BackrollBackup> 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<BackrollBackup> 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<BackrollBackup>();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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{
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
@ -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> T post(final String path, final JSONObject json, Class<T> 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> T get(String path, Class<T> 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> T delete(String path, Class<T> 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> T waitGet(String url, Class<T> 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");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue