package org.zstack.storage.fusionstor.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.fusionstor.backup.FusionstorBackupStorageBase.*; import org.zstack.storage.fusionstor.backup.FusionstorBackupStorageSimulatorConfig.FusionstorBackupStorageConfig; 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 FusionstorBackupStorageSimulator { CLogger logger = Utils.getLogger(FusionstorBackupStorageSimulator.class); @Autowired private FusionstorBackupStorageSimulatorConfig 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 FusionstorBackupStorageConfig 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(); FusionstorBackupStorageConfig c = config.config.get(name); if (c == null) { throw new CloudRuntimeException(String.format("cannot find FusionstorBackupStorageConfig by name[%s], uuid[%s]", name, cmd.getUuid())); } c.name = name; return c; } @RequestMapping(value= FusionstorBackupStorageBase.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) { FusionstorBackupStorageConfig c = getConfig(cmd); fsid = c.fsid; } rsp.fsid = fsid; reply(entity, rsp); return null; } @RequestMapping(value= FusionstorBackupStorageMonBase.PING_PATH, method= RequestMethod.POST) public @ResponseBody String pingMon(HttpEntity<String> entity) { FusionstorBackupStorageMonBase.PingCmd cmd = JSONObjectUtil.toObject(entity.getBody(), FusionstorBackupStorageMonBase.PingCmd.class); Boolean success = config.pingCmdSuccess.get(cmd.monUuid); FusionstorBackupStorageMonBase.PingRsp rsp = new FusionstorBackupStorageMonBase.PingRsp(); rsp.success = success == null ? true : success; if (!rsp.success) { rsp.error = "on purpose"; } Boolean operationFailure = config.pingCmdOperationFailure.get(cmd.monUuid); rsp.operationFailure = operationFailure == null ? false : operationFailure; reply(entity, rsp); return null; } @RequestMapping(value=FusionstorBackupStorageBase.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=FusionstorBackupStorageBase.INIT_PATH, method= RequestMethod.POST) public @ResponseBody String initialize(HttpEntity<String> entity) { InitCmd cmd = JSONObjectUtil.toObject(entity.getBody(), InitCmd.class); FusionstorBackupStorageConfig cbc = getConfig(cmd); config.initCmds.add(cmd); DebugUtils.Assert(cbc.fsid != null, String.format("fsid for fusionstor 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=FusionstorBackupStorageBase.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=FusionstorBackupStorageBase.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; } }