package org.zstack.storage.backup;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.transaction.annotation.Transactional;
import org.zstack.core.errorcode.ErrorFacade;
import org.zstack.header.core.workflow.FlowTrigger;
import org.zstack.header.core.workflow.NoRollbackFlow;
import org.zstack.header.errorcode.OperationFailureException;
import org.zstack.header.storage.backup.BackupStorageAllocationSpec;
import org.zstack.header.storage.backup.BackupStorageConstant.AllocatorParams;
import org.zstack.header.storage.backup.BackupStorageVO;
import org.zstack.utils.DebugUtils;
import org.zstack.utils.SizeUtils;
import static org.zstack.core.Platform.operr;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
*/
@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE)
public class BackupStorageReservedCapacityAllocatorFlow extends NoRollbackFlow {
@Autowired
private ErrorFacade errf;
@Override
@Transactional(readOnly = true)
public void run(FlowTrigger trigger, Map data) {
BackupStorageAllocationSpec spec = (BackupStorageAllocationSpec) data.get(AllocatorParams.SPEC);
List<BackupStorageVO> candidates = (List<BackupStorageVO>) data.get(AllocatorParams.CANDIDATES);
DebugUtils.Assert(candidates != null && !candidates.isEmpty(), "BackupStorageReservedCapacityAllocatorFlow cannot be the first element in the allocator chain");
List<BackupStorageVO> ret = new ArrayList<BackupStorageVO>();
long reservedCapacity = SizeUtils.sizeStringToBytes(BackupStorageGlobalConfig.RESERVED_CAPACITY.value());
for (BackupStorageVO vo : candidates) {
if (vo.getAvailableCapacity() - reservedCapacity > spec.getSize()) {
ret.add(vo);
}
}
if (ret.isEmpty()) {
throw new OperationFailureException(operr("after subtracting reserved capacity[%s], no backup storage has required capacity[%s bytes]",
BackupStorageGlobalConfig.RESERVED_CAPACITY.value(), spec.getSize()));
}
data.put(AllocatorParams.CANDIDATES, ret);
trigger.next();
}
}