package org.zstack.storage.ceph.backup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.zstack.core.db.DatabaseFacade;
import org.zstack.core.db.SimpleQuery;
import org.zstack.core.db.SimpleQuery.Op;
import org.zstack.header.exception.CloudRuntimeException;
import org.zstack.header.rest.RESTConstant;
import org.zstack.header.rest.RESTFacade;
import org.zstack.header.storage.backup.BackupStorageVO;
import org.zstack.header.storage.backup.BackupStorageVO_;
import org.zstack.storage.ceph.backup.CephBackupStorageBase.*;
import org.zstack.storage.ceph.backup.CephBackupStorageSimulatorConfig.CephBackupStorageConfig;
import org.zstack.utils.DebugUtils;
import org.zstack.utils.Utils;
import org.zstack.utils.gson.JSONObjectUtil;
import org.zstack.utils.logging.CLogger;
/**
* Created by frank on 7/28/2015.
*/
@Controller
public class CephBackupStorageSimulator {
CLogger logger = Utils.getLogger(CephBackupStorageSimulator.class);
@Autowired
private CephBackupStorageSimulatorConfig config;
@Autowired
private DatabaseFacade dbf;
@Autowired
private RESTFacade restf;
public void reply(HttpEntity<String> entity, Object rsp) {
String taskUuid = entity.getHeaders().getFirst(RESTConstant.TASK_UUID);
String callbackUrl = entity.getHeaders().getFirst(RESTConstant.CALLBACK_URL);
String rspBody = JSONObjectUtil.toJsonString(rsp);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setContentLength(rspBody.length());
headers.set(RESTConstant.TASK_UUID, taskUuid);
HttpEntity<String> rreq = new HttpEntity<String>(rspBody, headers);
restf.getRESTTemplate().exchange(callbackUrl, HttpMethod.POST, rreq, String.class);
}
private CephBackupStorageConfig getConfig(AgentCommand cmd) {
SimpleQuery<BackupStorageVO> q = dbf.createQuery(BackupStorageVO.class);
q.select(BackupStorageVO_.name);
q.add(BackupStorageVO_.uuid, Op.EQ, cmd.getUuid());
String name = q.findValue();
CephBackupStorageConfig c = config.config.get(name);
if (c == null) {
throw new CloudRuntimeException(String.format("cannot find CephBackupStorageConfig by name[%s], uuid[%s]", name, cmd.getUuid()));
}
c.name = name;
return c;
}
@RequestMapping(value= CephBackupStorageBase.GET_FACTS, method= RequestMethod.POST)
public @ResponseBody
String getFacts(HttpEntity<String> entity) {
GetFactsCmd cmd = JSONObjectUtil.toObject(entity.getBody(), GetFactsCmd.class);
GetFactsRsp rsp = new GetFactsRsp();
config.getFactsCmds.add(cmd);
String fsid = config.getFactsCmdFsid.get(cmd.monUuid);
if (fsid == null) {
CephBackupStorageConfig c = getConfig(cmd);
fsid = c.fsid;
}
rsp.fsid = fsid;
rsp.monAddr = config.monAddr.get(cmd.monUuid);
reply(entity, rsp);
return null;
}
@RequestMapping(value= CephBackupStorageMonBase.PING_PATH, method= RequestMethod.POST)
public @ResponseBody
String pingMon(HttpEntity<String> entity) {
CephBackupStorageMonBase.PingCmd cmd = JSONObjectUtil.toObject(entity.getBody(), CephBackupStorageMonBase.PingCmd.class);
Boolean success = config.pingCmdSuccess.get(cmd.monUuid);
CephBackupStorageMonBase.PingRsp rsp = new CephBackupStorageMonBase.PingRsp();
rsp.success = success == null ? true : success;
if (!rsp.success) {
rsp.error = "on purpose";
}
rsp.failure = config.pingCmdOperationFailure.get(cmd.monUuid);
reply(entity, rsp);
return null;
}
@RequestMapping(value=CephBackupStorageBase.GET_IMAGE_SIZE_PATH, method= RequestMethod.POST)
public @ResponseBody
String getImageSize(HttpEntity<String> entity) {
GetImageSizeCmd cmd = JSONObjectUtil.toObject(entity.getBody(), GetImageSizeCmd.class);
config.getImageSizeCmds.add(cmd);
GetImageSizeRsp rsp = new GetImageSizeRsp();
Long size = config.getImageSizeCmdSize.get(cmd.imageUuid);
rsp.size = size == null ? 0 : size;
Long asize = config.getImageSizeCmdActualSize.get(cmd.imageUuid);
rsp.actualSize = asize == null ? 0 : asize;
reply(entity, rsp);
return null;
}
@RequestMapping(value=CephBackupStorageBase.INIT_PATH, method= RequestMethod.POST)
public @ResponseBody
String initialize(HttpEntity<String> entity) {
InitCmd cmd = JSONObjectUtil.toObject(entity.getBody(), InitCmd.class);
CephBackupStorageConfig cbc = getConfig(cmd);
config.initCmds.add(cmd);
DebugUtils.Assert(cbc.fsid != null, String.format("fsid for ceph backup storage[%s] is null", cbc.name));
InitRsp rsp = new InitRsp();
if (!config.monInitSuccess) {
rsp.error = "on purpose";
rsp.success = false;
} else {
rsp.fsid = cbc.fsid;
rsp.totalCapacity = cbc.totalCapacity;
rsp.availableCapacity = cbc.availCapacity;
}
reply(entity, rsp);
return null;
}
@RequestMapping(value=CephBackupStorageBase.DOWNLOAD_IMAGE_PATH, method= RequestMethod.POST)
public @ResponseBody
String download(HttpEntity<String> entity) {
DownloadRsp rsp = new DownloadRsp();
DownloadCmd cmd = JSONObjectUtil.toObject(entity.getBody(), DownloadCmd.class);
config.downloadCmds.add(cmd);
Long size = config.imageSize.get(cmd.imageUuid);
rsp.setSize(size == null ? 0 : size);
Long asize = config.imageActualSize.get(cmd.imageUuid);
rsp.setActualSize(asize == null ? 0 : asize);
reply(entity, rsp);
return null;
}
@RequestMapping(value=CephBackupStorageBase.DELETE_IMAGE_PATH, method= RequestMethod.POST)
public @ResponseBody
String doDelete(HttpEntity<String> entity) {
DeleteCmd cmd = JSONObjectUtil.toObject(entity.getBody(), DeleteCmd.class);
config.deleteCmds.add(cmd);
DeleteRsp rsp = new DeleteRsp();
reply(entity, rsp);
return null;
}
@RequestMapping(value=CephBackupStorageBase.CHECK_IMAGE_METADATA_FILE_EXIST, method= RequestMethod.POST)
public @ResponseBody
String checkMetaDataFile(HttpEntity<String> entity) {
CheckImageMetaDataFileExistCmd cmd = JSONObjectUtil.toObject(entity.getBody(), CheckImageMetaDataFileExistCmd.class);
config.checkMetadataFileCmds.add(cmd);
CheckImageMetaDataFileExistRsp rsp = new CheckImageMetaDataFileExistRsp();
rsp.setExist(true);
rsp.setBackupStorageMetaFileName("bs_ceph_info.json");
reply(entity, rsp);
return null;
}
@RequestMapping(value=CephBackupStorageBase.DELETE_IMAGES_METADATA, method= RequestMethod.POST)
public @ResponseBody
String deleteImagesMetadata(HttpEntity<String> entity) {
DeleteImageInfoFromMetaDataFileCmd cmd = JSONObjectUtil.toObject(entity.getBody(), DeleteImageInfoFromMetaDataFileCmd.class);
config.deleteImageInfoFromMetadataFileCmds.add(cmd);
DeleteImageInfoFromMetaDataFileRsp rsp = new DeleteImageInfoFromMetaDataFileRsp();
rsp.setRet(0);
rsp.setOut("success delete");
reply(entity, rsp);
return null;
}
@RequestMapping(value=CephBackupStorageBase.DUMP_IMAGE_METADATA_TO_FILE, method= RequestMethod.POST)
public @ResponseBody
String dumpImagesMetadataToFile(HttpEntity<String> entity) {
DumpImageInfoToMetaDataFileCmd cmd = JSONObjectUtil.toObject(entity.getBody(), DumpImageInfoToMetaDataFileCmd.class);
config.dumpImageInfoToMetaDataFileCmds.add(cmd);
DumpImageInfoToMetaDataFileRsp rsp = new DumpImageInfoToMetaDataFileRsp();
rsp.setSuccess(true);
reply(entity, rsp);
return null;
}
@RequestMapping(value=CephBackupStorageBase.GET_IMAGES_METADATA, method= RequestMethod.POST)
public @ResponseBody
String getImagesMetadataToFile(HttpEntity<String> entity) {
GetImagesMetaDataCmd cmd = JSONObjectUtil.toObject(entity.getBody(), GetImagesMetaDataCmd.class);
config.getImageInfoToMetaDataFileCmds.add(cmd);
GetImagesMetaDataRsp rsp = new GetImagesMetaDataRsp();
rsp.setSuccess(true);
rsp.setImagesMetadata("{\"uuid\":\"a603e80ea18f424f8a5f00371d484537\",\"name\":\"test\",\"description\":\"\",\"state\":\"Enabled\",\"status\":\"Ready\",\"size\":19862528,\"actualSize\":15794176,\"md5Sum\":\"not calculated\",\"url\":\"http://192.168.200.1/mirror/diskimages/zstack-image-1.2.qcow2\",\"mediaType\":\"RootVolumeTemplate\",\"type\":\"zstack\",\"platform\":\"Linux\",\"format\":\"qcow2\",\"system\":false,\"createDate\":\"Dec 22, 2016 5:10:06 PM\",\"lastOpDate\":\"Dec 22, 2016 5:10:08 PM\",\"backupStorageRefs\":[{\"id\":45,\"imageUuid\":\"a603e80ea18f424f8a5f00371d484537\",\"backupStorageUuid\":\"63879ceb90764f839d3de772aa646c83\",\"installPath\":\"/bs-sftp/rootVolumeTemplates/acct-36c27e8ff05c4780bf6d2fa65700f22e/a603e80ea18f424f8a5f00371d484537/zstack-image-1.2.template\",\"status\":\"Ready\",\"createDate\":\"Dec 22, 2016 5:10:08 PM\",\"lastOpDate\":\"Dec 22, 2016 5:10:08 PM\"}]}");
reply(entity, rsp);
return null;
}
}