package org.zstack.storage.fusionstor.primary;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.zstack.core.cloudbus.CloudBus;
import org.zstack.core.db.DatabaseFacade;
import org.zstack.core.errorcode.ErrorFacade;
import org.zstack.core.timeout.ApiTimeoutManager;
import org.zstack.header.errorcode.ErrorCode;
import org.zstack.header.errorcode.OperationFailureException;
import org.zstack.header.host.HostConstant;
import org.zstack.header.message.MessageReply;
import org.zstack.header.vm.VmInstanceInventory;
import org.zstack.header.vm.VmInstanceMigrateExtensionPoint;
import org.zstack.header.volume.VolumeInventory;
import org.zstack.kvm.KVMAgentCommands.AgentCommand;
import org.zstack.kvm.KVMAgentCommands.AgentResponse;
import org.zstack.kvm.KVMHostAsyncHttpCallMsg;
import org.zstack.kvm.KVMHostAsyncHttpCallReply;
import org.zstack.storage.fusionstor.FusionstorConstants;
import org.zstack.utils.Utils;
import org.zstack.utils.logging.CLogger;

import javax.persistence.TypedQuery;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by frank on 6/16/2015.
 */


public class FusionstorPrimaryStorageVmMigrationExtension implements VmInstanceMigrateExtensionPoint {
    public static final String KVM_FUSIONSTOR_QUERY_PATH = "/fusionstor/query";

    public static class FusionstorQueryRsp extends AgentResponse {
        public String rsp;
    }

    public static class FusionstorQueryCmd extends AgentCommand {
        public String query;
    }

    private CLogger logger = Utils.getLogger(FusionstorPrimaryStorageVmMigrationExtension.class);
    private Map<String, List<VolumeInventory>> vmVolumes = new ConcurrentHashMap<String, List<VolumeInventory>>();

    @Autowired
    private CloudBus bus;
    @Autowired
    private DatabaseFacade dbf;
    @Autowired
    private ErrorFacade errf;
    @Autowired
    private ApiTimeoutManager timeoutMgr;

    @Transactional(readOnly = true)
    private boolean needLink(VmInstanceInventory inv) {
        String sql = "select ps.type from PrimaryStorageVO ps, VolumeVO vol where ps.uuid = vol.primaryStorageUuid" +
                " and vol.uuid = :uuid";
        TypedQuery<String> q = dbf.getEntityManager().createQuery(sql, String.class);
        q.setParameter("uuid", inv.getRootVolumeUuid());
        List<String> res = q.getResultList();
        if (res.isEmpty()) {
            return false;
        }

        String type = res.get(0);
        return FusionstorConstants.FUSIONSTOR_PRIMARY_STORAGE_TYPE.equals(type);
    }

    @Override
    public String preMigrateVm(VmInstanceInventory inv, String destHostUuid) {
        if (!needLink(inv)) {
            return null;
        }

        FusionstorQueryCmd cmd = new FusionstorQueryCmd();
        cmd.query = "query";

        KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg();
        msg.setCommand(cmd);
        msg.setCommandTimeout(timeoutMgr.getTimeout(cmd.getClass(), "5m"));
        msg.setPath(KVM_FUSIONSTOR_QUERY_PATH);
        msg.setHostUuid(destHostUuid);
        bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, destHostUuid);
        MessageReply reply = bus.call(msg);
        if (!reply.isSuccess()) {
            throw new OperationFailureException(reply.getError());
        }

        KVMHostAsyncHttpCallReply r = reply.castReply();
        FusionstorQueryRsp rsp = r.toResponse(FusionstorQueryRsp.class);
        if (!rsp.isSuccess()) {
            throw new OperationFailureException(errf.stringToOperationError(rsp.getError()));
        }

        return null;
    }

    @Override
    public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) {
    }

    @Override
    public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid) {
    }

    @Override
    public void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, ErrorCode reason) {
    }
}

@@ -984,24 +984,88 @@
 Constants;%0D%0A
+import org.zstack.storage.fusionstor.FusionstorGlobalProperty;%0D%0A
 import org.z
@@ -2704,25 +2704,30 @@
 sionstor
-Constants
+GlobalProperty
 .FUSIONS

fix FusionstorPrimaryStorageVmMigrationExtension.java