mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge remote-tracking branch 'origin/4.14'
This commit is contained in:
commit
567524a2a5
@ -492,6 +492,7 @@ public class EventTypes {
|
|||||||
public static final String EVENT_VM_BACKUP_RESTORE_VOLUME_TO_VM = "BACKUP.RESTORE.VOLUME.TO.VM";
|
public static final String EVENT_VM_BACKUP_RESTORE_VOLUME_TO_VM = "BACKUP.RESTORE.VOLUME.TO.VM";
|
||||||
public static final String EVENT_VM_BACKUP_SCHEDULE_CONFIGURE = "BACKUP.SCHEDULE.CONFIGURE";
|
public static final String EVENT_VM_BACKUP_SCHEDULE_CONFIGURE = "BACKUP.SCHEDULE.CONFIGURE";
|
||||||
public static final String EVENT_VM_BACKUP_SCHEDULE_DELETE = "BACKUP.SCHEDULE.DELETE";
|
public static final String EVENT_VM_BACKUP_SCHEDULE_DELETE = "BACKUP.SCHEDULE.DELETE";
|
||||||
|
public static final String EVENT_VM_BACKUP_USAGE_METRIC = "BACKUP.USAGE.METRIC";
|
||||||
|
|
||||||
// external network device events
|
// external network device events
|
||||||
public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";
|
public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";
|
||||||
|
|||||||
@ -20,14 +20,11 @@ package com.cloud.usage.dao;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.cloudstack.backup.Backup;
|
|
||||||
|
|
||||||
import com.cloud.usage.UsageBackupVO;
|
import com.cloud.usage.UsageBackupVO;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
import com.cloud.vm.VirtualMachine;
|
|
||||||
|
|
||||||
public interface UsageBackupDao extends GenericDao<UsageBackupVO, Long> {
|
public interface UsageBackupDao extends GenericDao<UsageBackupVO, Long> {
|
||||||
void updateMetrics(VirtualMachine vm, Backup.Metric metric);
|
void updateMetrics(Long vmId, Long size, Long virtualSize);
|
||||||
void removeUsage(Long accountId, Long zoneId, Long backupId);
|
void removeUsage(Long accountId, Long vmId, Date eventDate);
|
||||||
List<UsageBackupVO> getUsageRecords(Long accountId, Date startDate, Date endDate);
|
List<UsageBackupVO> getUsageRecords(Long accountId, Date startDate, Date endDate);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,69 +19,68 @@ package com.cloud.usage.dao;
|
|||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.apache.cloudstack.backup.Backup;
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.cloud.exception.CloudException;
|
||||||
import com.cloud.usage.UsageBackupVO;
|
import com.cloud.usage.UsageBackupVO;
|
||||||
import com.cloud.utils.DateUtil;
|
import com.cloud.utils.DateUtil;
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
import com.cloud.utils.db.QueryBuilder;
|
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import com.cloud.utils.db.Transaction;
|
|
||||||
import com.cloud.utils.db.TransactionCallback;
|
|
||||||
import com.cloud.utils.db.TransactionLegacy;
|
import com.cloud.utils.db.TransactionLegacy;
|
||||||
import com.cloud.utils.db.TransactionStatus;
|
|
||||||
import com.cloud.vm.VirtualMachine;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class UsageBackupDaoImpl extends GenericDaoBase<UsageBackupVO, Long> implements UsageBackupDao {
|
public class UsageBackupDaoImpl extends GenericDaoBase<UsageBackupVO, Long> implements UsageBackupDao {
|
||||||
public static final Logger LOGGER = Logger.getLogger(UsageBackupDaoImpl.class);
|
public static final Logger LOGGER = Logger.getLogger(UsageBackupDaoImpl.class);
|
||||||
protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, zone_id, account_id, domain_id, vm_id, backup_offering_id, size, protected_size, created, removed FROM cloud_usage.usage_backup WHERE " +
|
protected static final String UPDATE_DELETED = "UPDATE usage_backup SET removed = ? WHERE account_id = ? AND vm_id = ? and removed IS NULL";
|
||||||
|
protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, zone_id, account_id, domain_id, vm_id, backup_offering_id, size, protected_size, created, removed FROM usage_backup WHERE " +
|
||||||
" account_id = ? AND ((removed IS NULL AND created <= ?) OR (created BETWEEN ? AND ?) OR (removed BETWEEN ? AND ?) " +
|
" account_id = ? AND ((removed IS NULL AND created <= ?) OR (created BETWEEN ? AND ?) OR (removed BETWEEN ? AND ?) " +
|
||||||
" OR ((created <= ?) AND (removed >= ?)))";
|
" OR ((created <= ?) AND (removed >= ?)))";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateMetrics(final VirtualMachine vm, Backup.Metric metric) {
|
public void updateMetrics(final Long vmId, final Long size, final Long virtualSize) {
|
||||||
boolean result = Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<Boolean>() {
|
try (TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB)) {
|
||||||
@Override
|
SearchCriteria<UsageBackupVO> sc = this.createSearchCriteria();
|
||||||
public Boolean doInTransaction(final TransactionStatus status) {
|
sc.addAnd("vmId", SearchCriteria.Op.EQ, vmId);
|
||||||
final QueryBuilder<UsageBackupVO> qb = QueryBuilder.create(UsageBackupVO.class);
|
UsageBackupVO vo = findOneBy(sc);
|
||||||
qb.and(qb.entity().getVmId(), SearchCriteria.Op.EQ, vm.getId());
|
if (vo != null) {
|
||||||
final UsageBackupVO entry = findOneBy(qb.create());
|
vo.setSize(size);
|
||||||
if (entry == null) {
|
vo.setProtectedSize(virtualSize);
|
||||||
return false;
|
update(vo.getId(), vo);
|
||||||
}
|
|
||||||
entry.setSize(metric.getBackupSize());
|
|
||||||
entry.setProtectedSize(metric.getDataSize());
|
|
||||||
return update(entry.getId(), entry);
|
|
||||||
}
|
}
|
||||||
});
|
} catch (final Exception e) {
|
||||||
if (!result) {
|
LOGGER.error("Error updating backup metrics: " + e.getMessage(), e);
|
||||||
LOGGER.trace("Failed to update backup metrics for VM ID: " + vm.getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeUsage(Long accountId, Long zoneId, Long vmId) {
|
public void removeUsage(Long accountId, Long vmId, Date eventDate) {
|
||||||
boolean result = Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<Boolean>() {
|
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||||
@Override
|
try {
|
||||||
public Boolean doInTransaction(final TransactionStatus status) {
|
txn.start();
|
||||||
final QueryBuilder<UsageBackupVO> qb = QueryBuilder.create(UsageBackupVO.class);
|
try (PreparedStatement pstmt = txn.prepareStatement(UPDATE_DELETED);) {
|
||||||
qb.and(qb.entity().getAccountId(), SearchCriteria.Op.EQ, accountId);
|
if (pstmt != null) {
|
||||||
qb.and(qb.entity().getZoneId(), SearchCriteria.Op.EQ, zoneId);
|
pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), eventDate));
|
||||||
qb.and(qb.entity().getVmId(), SearchCriteria.Op.EQ, vmId);
|
pstmt.setLong(2, accountId);
|
||||||
final UsageBackupVO entry = findOneBy(qb.create());
|
pstmt.setLong(3, vmId);
|
||||||
return remove(qb.create()) > 0;
|
pstmt.executeUpdate();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
LOGGER.error("Error removing UsageBackupVO: " + e.getMessage(), e);
|
||||||
|
throw new CloudException("Remove backup usage exception: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
});
|
txn.commit();
|
||||||
if (!result) {
|
} catch (Exception e) {
|
||||||
LOGGER.warn("Failed to remove usage entry for backup of VM ID: " + vmId);
|
txn.rollback();
|
||||||
|
LOGGER.error("Exception caught while removing UsageBackupVO: " + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
txn.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -150,30 +150,28 @@ public class TransactionLegacy implements Closeable {
|
|||||||
|
|
||||||
public static TransactionLegacy open(final String name, final short databaseId, final boolean forceDbChange) {
|
public static TransactionLegacy open(final String name, final short databaseId, final boolean forceDbChange) {
|
||||||
TransactionLegacy txn = tls.get();
|
TransactionLegacy txn = tls.get();
|
||||||
boolean isNew = false;
|
|
||||||
if (txn == null) {
|
if (txn == null) {
|
||||||
if (s_logger.isTraceEnabled()) {
|
if (s_logger.isTraceEnabled()) {
|
||||||
s_logger.trace("Creating the transaction: " + name);
|
s_logger.trace("Creating the transaction: " + name);
|
||||||
}
|
}
|
||||||
txn = new TransactionLegacy(name, false, databaseId);
|
txn = new TransactionLegacy(name, false, databaseId);
|
||||||
tls.set(txn);
|
tls.set(txn);
|
||||||
isNew = true;
|
s_mbean.addTransaction(txn);
|
||||||
} else if (forceDbChange) {
|
} else if (forceDbChange) {
|
||||||
final short currentDbId = txn.getDatabaseId();
|
final short currentDbId = txn.getDatabaseId();
|
||||||
if (currentDbId != databaseId) {
|
if (currentDbId != databaseId) {
|
||||||
// we need to end the current transaction and switch databases
|
// we need to end the current transaction and switch databases
|
||||||
txn.close(txn.getName());
|
if (txn.close(txn.getName()) && txn.getCurrentConnection() == null) {
|
||||||
|
s_mbean.removeTransaction(txn);
|
||||||
|
}
|
||||||
|
|
||||||
txn = new TransactionLegacy(name, false, databaseId);
|
txn = new TransactionLegacy(name, false, databaseId);
|
||||||
tls.set(txn);
|
tls.set(txn);
|
||||||
isNew = true;
|
s_mbean.addTransaction(txn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
txn.checkConnection();
|
txn.checkConnection();
|
||||||
txn.takeOver(name, false);
|
txn.takeOver(name, false);
|
||||||
if (isNew) {
|
|
||||||
s_mbean.addTransaction(txn);
|
|
||||||
}
|
|
||||||
return txn;
|
return txn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,8 +760,8 @@ public class TransactionLegacy implements Closeable {
|
|||||||
}
|
}
|
||||||
_conn.close();
|
_conn.close();
|
||||||
_conn = null;
|
_conn = null;
|
||||||
|
s_mbean.removeTransaction(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final SQLException e) {
|
} catch (final SQLException e) {
|
||||||
s_logger.warn("Unable to close connection", e);
|
s_logger.warn("Unable to close connection", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,8 +87,13 @@ public class DummyBackupProvider extends AdapterBase implements BackupProvider {
|
|||||||
public Map<VirtualMachine, Backup.Metric> getBackupMetrics(Long zoneId, List<VirtualMachine> vms) {
|
public Map<VirtualMachine, Backup.Metric> getBackupMetrics(Long zoneId, List<VirtualMachine> vms) {
|
||||||
final Map<VirtualMachine, Backup.Metric> metrics = new HashMap<>();
|
final Map<VirtualMachine, Backup.Metric> metrics = new HashMap<>();
|
||||||
final Backup.Metric metric = new Backup.Metric(1000L, 100L);
|
final Backup.Metric metric = new Backup.Metric(1000L, 100L);
|
||||||
|
if (vms == null || vms.isEmpty()) {
|
||||||
|
return metrics;
|
||||||
|
}
|
||||||
for (VirtualMachine vm : vms) {
|
for (VirtualMachine vm : vms) {
|
||||||
metrics.put(vm, metric);
|
if (vm != null) {
|
||||||
|
metrics.put(vm, metric);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return metrics;
|
return metrics;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -216,9 +216,12 @@ public class VeeamBackupProvider extends AdapterBase implements BackupProvider,
|
|||||||
@Override
|
@Override
|
||||||
public Map<VirtualMachine, Backup.Metric> getBackupMetrics(final Long zoneId, final List<VirtualMachine> vms) {
|
public Map<VirtualMachine, Backup.Metric> getBackupMetrics(final Long zoneId, final List<VirtualMachine> vms) {
|
||||||
final Map<VirtualMachine, Backup.Metric> metrics = new HashMap<>();
|
final Map<VirtualMachine, Backup.Metric> metrics = new HashMap<>();
|
||||||
|
if (vms == null || vms.isEmpty()) {
|
||||||
|
return metrics;
|
||||||
|
}
|
||||||
final Map<String, Backup.Metric> backendMetrics = getClient(zoneId).getBackupMetrics();
|
final Map<String, Backup.Metric> backendMetrics = getClient(zoneId).getBackupMetrics();
|
||||||
for (final VirtualMachine vm : vms) {
|
for (final VirtualMachine vm : vms) {
|
||||||
if (!backendMetrics.containsKey(vm.getUuid())) {
|
if (vm == null || !backendMetrics.containsKey(vm.getUuid())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
metrics.put(vm, backendMetrics.get(vm.getUuid()));
|
metrics.put(vm, backendMetrics.get(vm.getUuid()));
|
||||||
|
|||||||
@ -84,7 +84,6 @@ import com.cloud.storage.Volume;
|
|||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
import com.cloud.storage.dao.DiskOfferingDao;
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
import com.cloud.storage.dao.VolumeDao;
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
import com.cloud.usage.dao.UsageBackupDao;
|
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
import com.cloud.user.AccountService;
|
import com.cloud.user.AccountService;
|
||||||
@ -126,8 +125,6 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||||||
@Inject
|
@Inject
|
||||||
private AccountManager accountManager;
|
private AccountManager accountManager;
|
||||||
@Inject
|
@Inject
|
||||||
private UsageBackupDao usageBackupDao;
|
|
||||||
@Inject
|
|
||||||
private VolumeDao volumeDao;
|
private VolumeDao volumeDao;
|
||||||
@Inject
|
@Inject
|
||||||
private DataCenterDao dataCenterDao;
|
private DataCenterDao dataCenterDao;
|
||||||
@ -1001,7 +998,6 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void runInContext() {
|
protected void runInContext() {
|
||||||
final int SYNC_INTERVAL = BackupSyncPollingInterval.value().intValue();
|
|
||||||
try {
|
try {
|
||||||
if (LOG.isTraceEnabled()) {
|
if (LOG.isTraceEnabled()) {
|
||||||
LOG.trace("Backup sync background task is running...");
|
LOG.trace("Backup sync background task is running...");
|
||||||
@ -1022,31 +1018,23 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync backup usage metrics
|
|
||||||
final Map<VirtualMachine, Backup.Metric> metrics = backupProvider.getBackupMetrics(dataCenter.getId(), new ArrayList<>(vms));
|
final Map<VirtualMachine, Backup.Metric> metrics = backupProvider.getBackupMetrics(dataCenter.getId(), new ArrayList<>(vms));
|
||||||
final GlobalLock syncBackupMetricsLock = GlobalLock.getInternLock("BackupSyncTask_metrics_zone_" + dataCenter.getId());
|
try {
|
||||||
if (syncBackupMetricsLock.lock(SYNC_INTERVAL)) {
|
for (final VirtualMachine vm : metrics.keySet()) {
|
||||||
try {
|
final Backup.Metric metric = metrics.get(vm);
|
||||||
for (final VirtualMachine vm : metrics.keySet()) {
|
if (metric != null) {
|
||||||
final Backup.Metric metric = metrics.get(vm);
|
// Sync out-of-band backups
|
||||||
if (metric != null) {
|
backupProvider.syncBackups(vm, metric);
|
||||||
usageBackupDao.updateMetrics(vm, metric);
|
// Emit a usage event, update usage metric for the VM by the usage server
|
||||||
}
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_BACKUP_USAGE_METRIC, vm.getAccountId(),
|
||||||
|
vm.getDataCenterId(), vm.getId(), "Backup-" + vm.getHostName() + "-" + vm.getUuid(),
|
||||||
|
vm.getBackupOfferingId(), null, metric.getBackupSize(), metric.getDataSize(),
|
||||||
|
Backup.class.getSimpleName(), vm.getUuid());
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
syncBackupMetricsLock.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
} catch (final Throwable e) {
|
||||||
|
if (LOG.isTraceEnabled()) {
|
||||||
// Sync out-of-band backups
|
LOG.trace("Failed to sync backup usage metrics and out-of-band backups");
|
||||||
for (final VirtualMachine vm : vms) {
|
|
||||||
final GlobalLock syncBackupsLock = GlobalLock.getInternLock("BackupSyncTask_backup_vm_" + vm.getId());
|
|
||||||
if (syncBackupsLock.lock(SYNC_INTERVAL)) {
|
|
||||||
try {
|
|
||||||
backupProvider.syncBackups(vm, metrics.get(vm));
|
|
||||||
} finally {
|
|
||||||
syncBackupsLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1081,7 +1081,10 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBackupEvent(String eventType) {
|
private boolean isBackupEvent(String eventType) {
|
||||||
return eventType != null && (eventType.equals(EventTypes.EVENT_VM_BACKUP_OFFERING_ASSIGN) || eventType.equals(EventTypes.EVENT_VM_BACKUP_OFFERING_REMOVE));
|
return eventType != null && (
|
||||||
|
eventType.equals(EventTypes.EVENT_VM_BACKUP_OFFERING_ASSIGN) ||
|
||||||
|
eventType.equals(EventTypes.EVENT_VM_BACKUP_OFFERING_REMOVE) ||
|
||||||
|
eventType.equals(EventTypes.EVENT_VM_BACKUP_USAGE_METRIC));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createVMHelperEvent(UsageEventVO event) {
|
private void createVMHelperEvent(UsageEventVO event) {
|
||||||
@ -1913,7 +1916,9 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
|
|||||||
final UsageBackupVO backupVO = new UsageBackupVO(zoneId, accountId, domainId, vmId, backupOfferingId, created);
|
final UsageBackupVO backupVO = new UsageBackupVO(zoneId, accountId, domainId, vmId, backupOfferingId, created);
|
||||||
usageBackupDao.persist(backupVO);
|
usageBackupDao.persist(backupVO);
|
||||||
} else if (EventTypes.EVENT_VM_BACKUP_OFFERING_REMOVE.equals(event.getType())) {
|
} else if (EventTypes.EVENT_VM_BACKUP_OFFERING_REMOVE.equals(event.getType())) {
|
||||||
usageBackupDao.removeUsage(accountId, zoneId, vmId);
|
usageBackupDao.removeUsage(accountId, vmId, event.getCreateDate());
|
||||||
|
} else if (EventTypes.EVENT_VM_BACKUP_USAGE_METRIC.equals(event.getType())) {
|
||||||
|
usageBackupDao.updateMetrics(vmId, event.getSize(), event.getVirtualSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user