package org.zstack.storage.primary.local; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.header.core.workflow.FlowChain; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.core.workflow.FlowDoneHandler; import org.zstack.header.core.workflow.FlowErrorHandler; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.storage.primary.PrimaryStorageAllocationSpec; import org.zstack.header.storage.primary.PrimaryStorageAllocatorStrategy; import org.zstack.header.storage.primary.PrimaryStorageConstant.AllocatorParams; import org.zstack.header.storage.primary.PrimaryStorageInventory; import org.zstack.header.storage.primary.PrimaryStorageVO; import org.zstack.storage.primary.DiskCapacityTracer; 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; /** * Created by frank on 7/1/2015. */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class LocalStorageAllocatorStrategy implements PrimaryStorageAllocatorStrategy { private FlowChainBuilder builder; @Autowired private DiskCapacityTracer tracker; public LocalStorageAllocatorStrategy(FlowChainBuilder builder) { this.builder = builder; } @Override public PrimaryStorageInventory allocate(PrimaryStorageAllocationSpec spec) { return allocateAllCandidates(spec).get(0); } @Override public List<PrimaryStorageInventory> allocateAllCandidates(PrimaryStorageAllocationSpec spec) { class Result { List<PrimaryStorageVO> result; ErrorCode errorCode; } final Result ret = new Result(); FlowChain allocatorChain = builder.build(); allocatorChain.setName(String.format("allocate-local-primary-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.result = (List<PrimaryStorageVO>) data.get(AllocatorParams.CANDIDATES); } }).error(new FlowErrorHandler(null) { @Override public void handle(ErrorCode errCode, Map data) { ret.errorCode = errCode; } }); tracker.trackAllocatorChain(allocatorChain); allocatorChain.start(); if (ret.errorCode != null) { throw new OperationFailureException(ret.errorCode); } else { List<PrimaryStorageInventory> invs = PrimaryStorageInventory.valueOf(ret.result); Collections.shuffle(invs); return invs; } } }