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.springframework.transaction.annotation.Transactional; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.core.db.SQLBatch; import org.zstack.header.storage.primary.PrimaryStorageCapacityUpdaterRunnable; import org.zstack.header.storage.primary.PrimaryStorageCapacityVO; import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; import org.zstack.storage.primary.local.LocalStorageKvmBackend.AgentResponse; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import javax.persistence.LockModeType; import javax.persistence.TypedQuery; import java.util.List; /** * Created by frank on 11/10/2015. */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class LocalStorageCapacityUpdater { private static CLogger logger = Utils.getLogger(LocalStorageCapacityUpdater.class); @Autowired private DatabaseFacade dbf; private void updateLocalStorageRef(AgentResponse rsp, LocalStorageHostRefVO ref) { if (ref.getAvailablePhysicalCapacity() == rsp.getAvailableCapacity() && ref.getTotalPhysicalCapacity() == rsp.getTotalCapacity()) { return; } long originalPhysicalTotal = ref.getTotalPhysicalCapacity(); long originalPhysicalAvailable = ref.getAvailablePhysicalCapacity(); ref.setTotalPhysicalCapacity(rsp.getTotalCapacity()); ref.setAvailablePhysicalCapacity(rsp.getAvailableCapacity()); dbf.getEntityManager().merge(ref); if (logger.isTraceEnabled()) { logger.trace(String.format("[Local Storage Capacity] changed the physical capacity of the host[uuid:%s] of " + "the local primary storage[uuid:%s] as:\n" + "physical total: %s --> %s\n" + "physical available: %s --> %s\n", ref.getHostUuid(), ref.getPrimaryStorageUuid(), originalPhysicalTotal, ref.getTotalPhysicalCapacity(), originalPhysicalAvailable, ref.getAvailablePhysicalCapacity())); } } public void updatePhysicalCapacityByKvmAgentResponse(String psUuid, String hostUuid, AgentResponse rsp) { new SQLBatch() { @Override protected void scripts() { LocalStorageHostRefVO ref = Q.New(LocalStorageHostRefVO.class).eq(LocalStorageHostRefVO_.primaryStorageUuid, psUuid) .eq(LocalStorageHostRefVO_.hostUuid, hostUuid).find(); if (ref == null) { return; } final long totalChange = rsp.getTotalCapacity() - ref.getTotalPhysicalCapacity(); final long availChange = rsp.getAvailableCapacity() - ref.getAvailablePhysicalCapacity(); new PrimaryStorageCapacityUpdater(psUuid).run(new PrimaryStorageCapacityUpdaterRunnable() { @Override public PrimaryStorageCapacityVO call(PrimaryStorageCapacityVO cap) { cap.setTotalPhysicalCapacity(cap.getTotalPhysicalCapacity() + totalChange); cap.setAvailablePhysicalCapacity(cap.getAvailablePhysicalCapacity() + availChange); return cap; } }); updateLocalStorageRef(rsp, ref); } }.execute(); } }