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.zstack.core.errorcode.ErrorFacade; import org.zstack.header.core.workflow.FlowChain; import org.zstack.header.core.workflow.FlowDoneHandler; import org.zstack.header.core.workflow.FlowErrorHandler; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.storage.backup.*; import org.zstack.header.storage.backup.BackupStorageConstant.AllocatorParams; import java.util.Collections; import java.util.List; import java.util.Map; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class DefaultBackupStorageAllocatorStrategy implements BackupStorageAllocatorStrategy { private FlowChain allocatorChain; @Autowired private ErrorFacade errf; public DefaultBackupStorageAllocatorStrategy(FlowChain allocatorChain) { this.allocatorChain = allocatorChain; } @Override public BackupStorageInventory allocate(BackupStorageAllocationSpec spec) throws BackupStorageException { return allocateAllCandidates(spec).get(0); } @Override public List<BackupStorageInventory> allocateAllCandidates(BackupStorageAllocationSpec spec) throws BackupStorageException { class Result { ErrorCode errorCode; List<BackupStorageVO> results; } final Result ret = new Result(); allocatorChain.setName(String.format("allocate-backup-storage-msg-%s", spec.getAllocationMessage().getId())); allocatorChain.setData(map(e(AllocatorParams.SPEC, spec))); allocatorChain.done(new FlowDoneHandler(null) { @Override public void handle(Map data) { ret.results = (List<BackupStorageVO>) data.get(AllocatorParams.CANDIDATES); } }).error(new FlowErrorHandler(null) { @Override public void handle(ErrorCode errCode, Map data) { ret.errorCode = errCode; } }).start(); if (ret.errorCode != null) { throw new BackupStorageException(errf.instantiateErrorCode(BackupStorageErrors.ALLOCATE_ERROR, "unable to allocate a backup storage", ret.errorCode)); } else { Collections.shuffle(ret.results); return BackupStorageInventory.valueOf(ret.results); } } }