mirror of https://github.com/apache/cloudstack.git
Fix backup dates (#6473)
Co-authored-by: João Paraquetti <joao@scclouds.com.br> Co-authored-by: dahn <daan.hoogland@gmail.com>
This commit is contained in:
parent
7049a6058d
commit
1065e9046b
|
|
@ -25,6 +25,8 @@ import org.apache.cloudstack.backup.Backup;
|
|||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@EntityReference(value = Backup.class)
|
||||
public class BackupResponse extends BaseResponse {
|
||||
|
||||
|
|
@ -50,7 +52,7 @@ public class BackupResponse extends BaseResponse {
|
|||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "backup date")
|
||||
private String date;
|
||||
private Date date;
|
||||
|
||||
@SerializedName(ApiConstants.SIZE)
|
||||
@Param(description = "backup size in bytes")
|
||||
|
|
@ -140,11 +142,11 @@ public class BackupResponse extends BaseResponse {
|
|||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return date;
|
||||
public Date getDate() {
|
||||
return this.date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import org.apache.cloudstack.backup.Backup;
|
|||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@EntityReference(value = Backup.RestorePoint.class)
|
||||
public class BackupRestorePointResponse extends BaseResponse {
|
||||
|
||||
|
|
@ -34,7 +36,7 @@ public class BackupRestorePointResponse extends BaseResponse {
|
|||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "created time")
|
||||
private String created;
|
||||
private Date created;
|
||||
|
||||
@SerializedName(ApiConstants.TYPE)
|
||||
@Param(description = "restore point type")
|
||||
|
|
@ -48,11 +50,11 @@ public class BackupRestorePointResponse extends BaseResponse {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
return created;
|
||||
public Date getCreated() {
|
||||
return this.created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
|
@ -58,10 +60,10 @@ public interface Backup extends ControlledEntity, InternalIdentity, Identity {
|
|||
|
||||
class RestorePoint {
|
||||
private String id;
|
||||
private String created;
|
||||
private Date created;
|
||||
private String type;
|
||||
|
||||
public RestorePoint(String id, String created, String type) {
|
||||
public RestorePoint(String id, Date created, String type) {
|
||||
this.id = id;
|
||||
this.created = created;
|
||||
this.type = type;
|
||||
|
|
@ -75,11 +77,11 @@ public interface Backup extends ControlledEntity, InternalIdentity, Identity {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
return created;
|
||||
public Date getCreated() {
|
||||
return this.created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +136,7 @@ public interface Backup extends ControlledEntity, InternalIdentity, Identity {
|
|||
long getVmId();
|
||||
String getExternalId();
|
||||
String getType();
|
||||
String getDate();
|
||||
Date getDate();
|
||||
Backup.Status getStatus();
|
||||
Long getSize();
|
||||
Long getProtectedSize();
|
||||
|
|
|
|||
|
|
@ -17,16 +17,27 @@
|
|||
package com.cloud.upgrade.dao;
|
||||
|
||||
import com.cloud.upgrade.SystemVmTemplateRegistration;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class Upgrade41810to41900 implements DbUpgrade, DbUpgradeSystemVmTemplate {
|
||||
final static Logger LOG = Logger.getLogger(Upgrade41810to41900.class);
|
||||
private SystemVmTemplateRegistration systemVmTemplateRegistration;
|
||||
|
||||
private final SimpleDateFormat[] formats = {
|
||||
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"), new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"),
|
||||
new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy")};
|
||||
|
||||
@Override
|
||||
public String[] getUpgradableVersionRange() {
|
||||
return new String[] {"4.18.1.0", "4.19.0.0"};
|
||||
|
|
@ -55,6 +66,7 @@ public class Upgrade41810to41900 implements DbUpgrade, DbUpgradeSystemVmTemplate
|
|||
|
||||
@Override
|
||||
public void performDataMigration(Connection conn) {
|
||||
migrateBackupDates(conn);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -82,4 +94,103 @@ public class Upgrade41810to41900 implements DbUpgrade, DbUpgradeSystemVmTemplate
|
|||
throw new CloudRuntimeException("Failed to find / register SystemVM template(s)");
|
||||
}
|
||||
}
|
||||
|
||||
public void migrateBackupDates(Connection conn) {
|
||||
LOG.info("Trying to convert backups' date column from varchar(255) to datetime type.");
|
||||
|
||||
modifyDateColumnNameAndCreateNewOne(conn);
|
||||
fetchDatesAndMigrateToNewColumn(conn);
|
||||
dropOldColumn(conn);
|
||||
|
||||
LOG.info("Finished converting backups' date column from varchar(255) to datetime.");
|
||||
}
|
||||
|
||||
private void modifyDateColumnNameAndCreateNewOne(Connection conn) {
|
||||
String alterColumnName = "ALTER TABLE `cloud`.`backups` CHANGE COLUMN `date` `old_date` varchar(255);";
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(alterColumnName)) {
|
||||
pstmt.execute();
|
||||
} catch (SQLException e) {
|
||||
String message = String.format("Unable to alter backups' date column name due to [%s].", e.getMessage());
|
||||
LOG.error(message, e);
|
||||
throw new CloudRuntimeException(message, e);
|
||||
}
|
||||
|
||||
String createNewColumn = "ALTER TABLE `cloud`.`backups` ADD COLUMN `date` DATETIME;";
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(createNewColumn)) {
|
||||
pstmt.execute();
|
||||
} catch (SQLException e) {
|
||||
String message = String.format("Unable to crate new backups' column date due to [%s].", e.getMessage());
|
||||
LOG.error(message, e);
|
||||
throw new CloudRuntimeException(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchDatesAndMigrateToNewColumn(Connection conn) {
|
||||
String selectBackupDates = "SELECT `id`, `old_date` FROM `cloud`.`backups` WHERE 1;";
|
||||
String date;
|
||||
java.sql.Date reformatedDate;
|
||||
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(selectBackupDates)) {
|
||||
try (ResultSet result = pstmt.executeQuery()) {
|
||||
while (result.next()) {
|
||||
date = result.getString("old_date");
|
||||
reformatedDate = tryToTransformStringToDate(date);
|
||||
updateBackupDate(conn, result.getLong("id"), reformatedDate);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
String message = String.format("Unable to retrieve backup dates due to [%s].", e.getMessage());
|
||||
LOG.error(message, e);
|
||||
throw new CloudRuntimeException(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
private java.sql.Date tryToTransformStringToDate(String date) {
|
||||
Date parsedDate = null;
|
||||
try {
|
||||
parsedDate = DateUtil.parseTZDateString(date);
|
||||
} catch (ParseException e) {
|
||||
for (SimpleDateFormat sdf: formats) {
|
||||
try {
|
||||
parsedDate = sdf.parse(date);
|
||||
} catch (ParseException ex) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (parsedDate == null) {
|
||||
String msg = String.format("Unable to parse date [%s]. Will change backup date to null.", date);
|
||||
LOG.error(msg);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new java.sql.Date(parsedDate.getTime());
|
||||
}
|
||||
|
||||
private void updateBackupDate(Connection conn, long id, java.sql.Date date) {
|
||||
String updateBackupDate = "UPDATE `cloud`.`backups` SET `date` = ? WHERE `id` = ?;";
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(updateBackupDate)) {
|
||||
pstmt.setDate(1, date);
|
||||
pstmt.setLong(2, id);
|
||||
|
||||
pstmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
String message = String.format("Unable to update backup date with id [%s] to date [%s] due to [%s].", id, date, e.getMessage());
|
||||
LOG.error(message, e);
|
||||
throw new CloudRuntimeException(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void dropOldColumn(Connection conn) {
|
||||
String dropOldColumn = "ALTER TABLE `cloud`.`backups` DROP COLUMN `old_date`;";
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(dropOldColumn)) {
|
||||
pstmt.execute();
|
||||
} catch (SQLException e) {
|
||||
String message = String.format("Unable to drop old_date column due to [%s].", e.getMessage());
|
||||
LOG.error(message, e);
|
||||
throw new CloudRuntimeException(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
|
|
@ -27,6 +28,8 @@ import javax.persistence.GeneratedValue;
|
|||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
@Entity
|
||||
@Table(name = "backups")
|
||||
|
|
@ -49,7 +52,8 @@ public class BackupVO implements Backup {
|
|||
private String backupType;
|
||||
|
||||
@Column(name = "date")
|
||||
private String date;
|
||||
@Temporal(value = TemporalType.DATE)
|
||||
private Date date;
|
||||
|
||||
@Column(name = "size")
|
||||
private Long size;
|
||||
|
|
@ -114,11 +118,11 @@ public class BackupVO implements Backup {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getDate() {
|
||||
return date;
|
||||
public Date getDate() {
|
||||
return this.date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public class DummyBackupProvider extends AdapterBase implements BackupProvider {
|
|||
backup.setVmId(vm.getId());
|
||||
backup.setExternalId("dummy-external-id");
|
||||
backup.setType("FULL");
|
||||
backup.setDate(new Date().toString());
|
||||
backup.setDate(new Date());
|
||||
backup.setSize(1024L);
|
||||
backup.setProtectedSize(1024000L);
|
||||
backup.setStatus(Backup.Status.BackedUp);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ import javax.inject.Inject;
|
|||
import java.net.URISyntaxException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -605,7 +607,14 @@ public class NetworkerBackupProvider extends AdapterBase implements BackupProvid
|
|||
strayBackup.setVmId(vm.getId());
|
||||
strayBackup.setExternalId(strayNetworkerBackup.getId());
|
||||
strayBackup.setType(strayNetworkerBackup.getType());
|
||||
strayBackup.setDate(strayNetworkerBackup.getSaveTime());
|
||||
SimpleDateFormat formatterDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
|
||||
try {
|
||||
strayBackup.setDate(formatterDateTime.parse(strayNetworkerBackup.getSaveTime()));
|
||||
} catch (ParseException e) {
|
||||
String msg = String.format("Unable to parse date [%s].", strayNetworkerBackup.getSaveTime());
|
||||
LOG.error(msg, e);
|
||||
throw new CloudRuntimeException(msg, e);
|
||||
}
|
||||
strayBackup.setStatus(Backup.Status.BackedUp);
|
||||
for ( Backup.VolumeInfo thisVMVol : vm.getBackupVolumeList()) {
|
||||
vmBackupSize += (thisVMVol.getSize() / 1024L /1024L);
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ public class NetworkerClient {
|
|||
|
||||
SimpleDateFormat formatterDate = new SimpleDateFormat("yyyy-MM-dd");
|
||||
SimpleDateFormat formatterTime = new SimpleDateFormat("HH:mm:ss");
|
||||
SimpleDateFormat formatterDateTime = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss");
|
||||
SimpleDateFormat formatterDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||
|
||||
String startDate = formatterDate.format(backupJobStart);
|
||||
String startTime = formatterTime.format(backupJobStart);
|
||||
|
|
@ -252,7 +252,13 @@ public class NetworkerClient {
|
|||
backup.setVmId(vm.getId());
|
||||
backup.setExternalId(networkerLatestBackup.getId());
|
||||
backup.setType(networkerLatestBackup.getType());
|
||||
backup.setDate(networkerLatestBackup.getCreationTime());
|
||||
try {
|
||||
backup.setDate(formatterDateTime.parse(networkerLatestBackup.getCreationTime()));
|
||||
} catch (ParseException e) {
|
||||
String msg = String.format("Unable to parse date [%s].", networkerLatestBackup.getCreationTime());
|
||||
LOG.error(msg, e);
|
||||
throw new CloudRuntimeException(msg, e);
|
||||
}
|
||||
backup.setSize(networkerLatestBackup.getSize().getValue());
|
||||
backup.setProtectedSize(networkerLatestBackup.getSize().getValue());
|
||||
backup.setStatus(org.apache.cloudstack.backup.Backup.Status.BackedUp);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.UUID;
|
||||
import java.util.Date;
|
||||
import java.util.Calendar;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
|
@ -660,7 +662,7 @@ public class VeeamClient {
|
|||
private Backup.RestorePoint getRestorePointFromBlock(String[] parts) {
|
||||
LOG.debug(String.format("Processing block of restore points: [%s].", StringUtils.join(parts, ", ")));
|
||||
String id = null;
|
||||
String created = null;
|
||||
Date created = null;
|
||||
String type = null;
|
||||
for (String part : parts) {
|
||||
if (part.matches("Id(\\s)+:(.)*")) {
|
||||
|
|
@ -668,7 +670,11 @@ public class VeeamClient {
|
|||
id = split[1].trim();
|
||||
} else if (part.matches("CreationTime(\\s)+:(.)*")) {
|
||||
String [] split = part.split(":", 2);
|
||||
created = split[1].trim();
|
||||
split[1] = StringUtils.trim(split[1]);
|
||||
String [] time = split[1].split("[:/ ]");
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Integer.parseInt(time[2]), Integer.parseInt(time[0]) - 1, Integer.parseInt(time[1]), Integer.parseInt(time[3]), Integer.parseInt(time[4]), Integer.parseInt(time[5]));
|
||||
created = cal.getTime();
|
||||
} else if (part.matches("Type(\\s)+:(.)*")) {
|
||||
String [] split = part.split(":");
|
||||
type = split[1].trim();
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@
|
|||
<status :text="text ? text : ''" />{{ text }}
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template v-slot:created="{ item }">
|
||||
{{ $toLocaleDate(item) }}
|
||||
</template>
|
||||
|
||||
</a-table>
|
||||
|
||||
<div v-if="!defaultPagination" style="display: block; text-align: right; margin-top: 10px;">
|
||||
|
|
|
|||
Loading…
Reference in New Issue