diff --git a/src/main/java/com/educoder/bridge/common/settings/AppConfig.java b/src/main/java/com/educoder/bridge/common/settings/AppConfig.java index 90b5107..32a1485 100644 --- a/src/main/java/com/educoder/bridge/common/settings/AppConfig.java +++ b/src/main/java/com/educoder/bridge/common/settings/AppConfig.java @@ -84,6 +84,9 @@ public class AppConfig { @Value("${k8s.serverUrl}") private String k8sServerUrl; + @Value("${singleEvaCodePath}") + private String singleEvaCodePath; + private String bridgeInstanceName = IpUtils.getLocalIp(); public String getServerUrl() { @@ -222,4 +225,7 @@ public class AppConfig { return bridgeInstanceName; } + public String getSingleEvaCodePath() { + return singleEvaCodePath; + } } diff --git a/src/main/java/com/educoder/bridge/game/controller/GameController.java b/src/main/java/com/educoder/bridge/game/controller/GameController.java index c8af042..3b5f106 100644 --- a/src/main/java/com/educoder/bridge/game/controller/GameController.java +++ b/src/main/java/com/educoder/bridge/game/controller/GameController.java @@ -1,8 +1,10 @@ package com.educoder.bridge.game.controller; import java.io.File; +import java.nio.channels.InterruptibleChannel; import java.time.LocalDateTime; +import com.educoder.bridge.game.thread.SingleEvaThread; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -212,6 +214,112 @@ public class GameController { return response; } + /** + * 单个文件评测 + */ + @RequestMapping(path = "/singleEvaluate") + @ApiOperation(value = "单个文件评测", httpMethod = "POST", produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + public JSONObject singleEvaluate( + @ApiParam(name = "tpiID", required = true, value = "实训实例的ID") @RequestParam String tpiID, + @ApiParam(name = "buildID", required = true, value = "本次评测ID") @RequestParam String buildID, + @ApiParam(name = "isPublished", required = false, value = "实训是否已经发布,1代表调试模式,实训未发布") @RequestParam Integer isPublished, + @ApiParam(name = "instanceChallenge", required = true, value = "当前处在第几关") @RequestParam String instanceChallenge, + @ApiParam(name = "testCases", required = true, value = "测试用例") @RequestParam String testCases, + @ApiParam(name = "codeFileName", required = true, value = "代码文件名") @RequestParam String codeFileName, + @ApiParam(name = "evaScriptType", required = true, value = "代码评测脚本类型") @RequestParam String evaScriptType, + @ApiParam(name = "codeFile", required = true, value = "代码文件") @RequestParam String codeFile, + @ApiParam(name = "timeLimit", required = false, value = "时间限制") Integer timeLimit, + @ApiParam(name = "resubmit", required = true, value = "是否是重复评测") @RequestParam String resubmit, + @ApiParam(name = "needPortMapping", required = false, value = "容器中需要被映射的端口") Integer needPortMapping, + @ApiParam(name = "podType", required = true, value = "pod类型(0.evaluate,1.webssh,2.evassh)") @RequestParam Integer podType, + @ApiParam(name = "file", required = false, value = "需要传文件的实训,给出文件存放路径(一个目录)及文件类型") String file, + @ApiParam(name = "containers", required = true, value = "需要使用的容器,base64编码") @RequestParam String containers, + @ApiParam(name = "sec_key", required = false, value = "每一次评测的唯一标识") String sec_key) throws Exception { + logger.info("[start]单个文件评测:tpiID: {}, buildID: {}, isPublished: {}, instanceChallenge: {}, " + + "testCases: {}, codeFile: {}, timeLimit: {}, resubmit: {}, " + + "needPortMapping: {}, podType: {}, file: {}, containers: {}, sec_key: {}", + tpiID, buildID, isPublished, instanceChallenge, testCases, codeFile, timeLimit, resubmit, + needPortMapping, podType, file, containers, sec_key); + + // 记录开始时间 + LocalDateTime requestTime = LocalDateTime.now(); + String evaluateStartTime = requestTime.toString(); + JSONObject cost = new JSONObject(); + cost.put("evaluateStartTime", evaluateStartTime); + JedisUtil.set("timeCost:" + tpiID + ":" + buildID, cost.toJSONString()); + + JSONObject response = new JSONObject(); + + // 参数处理 + needPortMapping = needPortMapping == null ? 0 : needPortMapping; + timeLimit = timeLimit == null ? Integer.parseInt(appConfig.getDefaultTimeLimit()) : timeLimit; + testCases = Base64Util.decode(testCases); + containers = Base64Util.decode(containers); + + // 每次评测均生成新TPI评测脚本 + String tpiWorkspace = TpUtils.buildTpiWorkspace(appConfig.getWorkspace(), tpiID); + gameService.generateEvaluateShellScript(tpiWorkspace, evaScriptType); + codeFile = Base64Util.decode(codeFile); + gameService.generateEvaluateCodeFile(tpiWorkspace, codeFileName, codeFile, instanceChallenge); + + String tpiRepoPath = TpUtils.buildTpiRepoPath(tpiWorkspace, appConfig.getSingleEvaCodePath().split("/")[0]); + + JSONObject buildParams = new JSONObject(true); + buildParams.put("tpiID", tpiID); + buildParams.put("buildID", buildID); + buildParams.put("isPublished", isPublished); + buildParams.put("instanceChallenge", instanceChallenge); + buildParams.put("testCases", testCases); + buildParams.put("timeLimit", timeLimit); + buildParams.put("resubmit", resubmit); + buildParams.put("needPortMapping", needPortMapping); + buildParams.put("podType", podType); + buildParams.put("containers", containers); + buildParams.put("codeFileName", codeFileName); + buildParams.put("sec_key", sec_key); + buildParams.put("tpiRepoPath", tpiRepoPath); + + // 若实训生成文件 todo:这个处理方式好2b,扩展性极差 + if (!StringUtils.isEmpty(file)) { + file = Base64Util.decode(file); + buildParams.put("file", file); + // 清空目标文件夹以防止影响此次评测结果 + GameHelper.clearFiles(tpiRepoPath + File.separator + + JSONObject.parseObject(file).getString("path")); + } + + // podName + String podName = podType != 2 ? "evaluate-" + tpiID : "evassh-" + tpiID; + + BridgePod bridgePod = bridgePodService.createBridgePod(podName, tpiID, requestTime, sec_key); + buildParams.put("bridgePodId", bridgePod.getId()); + + // 若需要端口映射服务,则分配端口,将podName-port键值对存储于redis + String port = "-1"; + if (needPortMapping != -1) { + port = portService.allocatePort() + ""; + JedisUtil.hset("port", podName, port); + } + +// sendSingleToKafka(buildParams, tpiID, requestTime); + + response.put("ableToCreate", 1); + response.put("costTime", System.currentTimeMillis() - TimeHelper.convertTimeToMillis(evaluateStartTime)); + response.put("waitNum", 0); + response.put("code", 0); + response.put("port", port); + response.put("msg", "评测完成"); + + logger.info("[end]单个文件评测:tpiID: {}, buildID: {}", tpiID, buildID); + + return response; + } + + private void sendSingleToKafka(JSONObject buildparams, String tpiID, final LocalDateTime requestTime) { + SingleEvaThread singleEvaThread = gameService.getSingleEvaThread(buildparams); + threadPoolTaskExecutor.execute(singleEvaThread); + } + private void sendToKafka(JSONObject buildParams, String tpiID, final LocalDateTime requestTime) { BuildThread buildThread = gameService.getBuildThread(buildParams); threadPoolTaskExecutor.execute(buildThread); diff --git a/src/main/java/com/educoder/bridge/game/service/GameService.java b/src/main/java/com/educoder/bridge/game/service/GameService.java index 22c1c46..91fecc0 100644 --- a/src/main/java/com/educoder/bridge/game/service/GameService.java +++ b/src/main/java/com/educoder/bridge/game/service/GameService.java @@ -13,11 +13,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.educoder.bridge.game.thread.SingleEvaThread; +import com.educoder.bridge.k8s.service.EvaScriptService; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; @@ -67,6 +68,9 @@ public class GameService { @Autowired ResourceFileService resourceFileService; + @Autowired + private EvaScriptService evaScriptService; + private static final Logger logger = LoggerFactory.getLogger(GameService.class); /** @@ -679,7 +683,18 @@ public class GameService { BuildThread buildThread = (BuildThread) BeanFactory.getObejct("BuildThread"); buildThread.setBuildParams(buildParams); return buildThread; + } + /** + * 根据单个文件评测信息,构建一个singleEvaThread + * + * @param buildParams + * @return + */ + public SingleEvaThread getSingleEvaThread(JSONObject buildParams) { + SingleEvaThread singleEvaThread = (SingleEvaThread) BeanFactory.getObejct("singleEvaThread"); + singleEvaThread.setBuildParams(buildParams); + return singleEvaThread; } /** @@ -824,4 +839,51 @@ public class GameService { return result; } + public void generateEvaluateShellScript(String tpiWorkspace, String evaScriptType) throws GameException { + logger.debug("tpiWorkspace: {}, evaScriptType: {}", tpiWorkspace, evaScriptType); + + // 获取脚本 + String script = evaScriptService.getScriptByType(evaScriptType); + if (StringUtils.isEmpty(script)) { + logger.error("生成评测脚本失败: 无评测脚本"); + + throw new GameException(-1, "生成评测脚本失败: 无评测脚本"); + } + script = Base64Util.decode(script); + + try { + // 写脚本到工作空间目录下 + FileUtils.deleteQuietly(new File(tpiWorkspace + File.separator + "evaluate.sh")); + FileUtils.writeStringToFile(new File(tpiWorkspace + File.separator + "evaluate.sh"), script, "UTF-8"); + } catch (Exception e) { + logger.error("生成评测脚本失败!{}", e); + + throw new GameException(-1, "生成评测脚本失败"); + } + + try { + String content = resourceFileService.getResourceFileContent("evaluate/execeva.sh"); + FileUtils.deleteQuietly(new File(tpiWorkspace + File.separator + "execeva.sh")); + FileUtils.writeStringToFile(new File(tpiWorkspace + File.separator + "execeva.sh"), content, "UTF-8"); + } catch (Exception e) { + logger.error("生成评测脚本execeva失败!{}", e); + + throw new GameException(-1, "生成评测脚本execeva失败"); + } + } + + public void generateEvaluateCodeFile(String tpiWorkspace, String codeFileName, String codeFile, String instanceChallenge) throws GameException { + + logger.debug("生成评测代码文件: tpiWorkspace: {}, codeFileName: {}, codeFile: {}, instanceChallenge: {}", tpiWorkspace, codeFileName, codeFile, instanceChallenge); + String codeFilePath = tpiWorkspace + File.separator + appConfig.getSingleEvaCodePath() + instanceChallenge + File.separator + codeFileName; + try { + // 写脚本到工作空间目录下 + FileUtils.deleteQuietly(new File(codeFilePath)); + FileUtils.writeStringToFile(new File(codeFilePath), codeFile, "UTF-8"); + } catch (Exception e) { + logger.error("生成评测代码文件失败!{}", e); + + throw new GameException(-1, "生成评测代码文件失败"); + } + } } diff --git a/src/main/java/com/educoder/bridge/game/service/KubernetesService.java b/src/main/java/com/educoder/bridge/game/service/KubernetesService.java index 8f069e0..3064816 100644 --- a/src/main/java/com/educoder/bridge/game/service/KubernetesService.java +++ b/src/main/java/com/educoder/bridge/game/service/KubernetesService.java @@ -1,6 +1,7 @@ package com.educoder.bridge.game.service; +import java.io.File; import java.time.Duration; import java.time.Instant; @@ -50,7 +51,7 @@ public class KubernetesService { * 在pod中执行评测脚本 */ public void executeShellInPod(JSONObject buildParams, Pod pod, int needPortMapping, int timeLimit, int isPublished, - int instanceChallenge, String testCases) { + int instanceChallenge, String testCases, Boolean isSingleEva) { String podName = pod.getMetadata().getName(); logger.debug("podName: {}, needPortMapping: {}, timeLimit: {}, isPublished: {}, instanceChallenge: {}", podName, needPortMapping, timeLimit, isPublished, instanceChallenge); @@ -67,7 +68,12 @@ public class KubernetesService { String buildID = buildParams.getString("buildID"); String tpiWorkspace = TpUtils.buildTpiWorkspace(appConfig.getWorkspace(), tpiID); String shFile = tpiWorkspace + "/evaluate.sh"; - String command = " timeout " + timeLimit + " kubectl exec " + podName + " timeout " + timeLimit + " bash " + shFile + " " + instanceChallenge + " " + ins; + String command = " timeout " + timeLimit + " kubectl exec " + podName + " timeout " + timeLimit + " bash " + shFile + " " + instanceChallenge + " " + ins; + if (isSingleEva) { + String codeFileName = buildParams.getString("codeFileName"); + String challengeProgramName = tpiWorkspace + File.separator + appConfig.getSingleEvaCodePath() + instanceChallenge + File.separator + codeFileName; + command = " timeout " + timeLimit + " kubectl exec " + podName + " timeout " + timeLimit + " bash " + shFile + " " + challengeProgramName + " " + ins; + } logger.info("evaluate command: {}", command); // 为pod的score加1,若pod之前不存在,则score为1 JedisUtil.zup("taskNum", podName); diff --git a/src/main/java/com/educoder/bridge/game/thread/BuildThread.java b/src/main/java/com/educoder/bridge/game/thread/BuildThread.java index e078f51..5570589 100644 --- a/src/main/java/com/educoder/bridge/game/thread/BuildThread.java +++ b/src/main/java/com/educoder/bridge/game/thread/BuildThread.java @@ -179,7 +179,7 @@ public class BuildThread extends Thread { : buildParams.getInteger("executeTime"); kubernetesService.executeShellInPod(buildParams, podRef.getPod(), buildParams.getInteger("needPortMapping"), executeTimeLimit, buildParams.getInteger("isPublished"), buildParams.getInteger("instanceChallenge"), - buildParams.getString("testCases")); + buildParams.getString("testCases"), Boolean.FALSE); } diff --git a/src/main/java/com/educoder/bridge/game/thread/SingleEvaThread.java b/src/main/java/com/educoder/bridge/game/thread/SingleEvaThread.java new file mode 100644 index 0000000..7d9c9f6 --- /dev/null +++ b/src/main/java/com/educoder/bridge/game/thread/SingleEvaThread.java @@ -0,0 +1,129 @@ +package com.educoder.bridge.game.thread; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.educoder.bridge.common.constant.BuildResultCsts; +import com.educoder.bridge.common.settings.AppConfig; +import com.educoder.bridge.common.utils.GameHelper; +import com.educoder.bridge.game.model.PodRef; +import com.educoder.bridge.game.service.GameService; +import com.educoder.bridge.game.service.K8sService; +import com.educoder.bridge.game.service.KubernetesService; +import com.educoder.bridge.k8s.service.RunPodService; +import io.fabric8.kubernetes.api.model.Pod; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; + +import java.time.Duration; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; + +/** + * 单个文件评测线程 + */ + +@Service("singleEvaThread") +@Scope("prototype") +public class SingleEvaThread extends Thread { + private final Logger logger = LoggerFactory.getLogger(getClass()); + @Autowired + private GameService gameService; + @Autowired + private KubernetesService kubernetesService; + @Autowired + private AppConfig appConfig; + @Autowired + private K8sService k8sService; + @Autowired + private RunPodService runPodService; + + private JSONObject buildParams; + + public SingleEvaThread() { + } + + public SingleEvaThread(JSONObject buildParams) { + this(); + this.buildParams = buildParams; + } + + public void setBuildParams(JSONObject buildParams) { + this.buildParams = buildParams; + } + + public JSONObject getBuildParams() { + return buildParams; + } + + @Override + public void run() { + String tpiID = buildParams.getString("tpiID"); + String buildID = buildParams.getString("buildID"); + Map podInLabels = new HashMap<>(1); + Map podNotInLabels = new HashMap<>(1); + podInLabels.put("tpiID", tpiID); + podInLabels.put("type", "evaluate,evassh"); + String type = buildParams.getInteger("podType") != 2 ? "evaluate" : "evassh"; + + String testCases = buildParams.getString("testCases"); + String out = GameHelper.getTextMsgResult("服务启动中..."); + gameService.encapsulateStepByStepResult(out, buildParams, testCases); + + Instant podStartInstant = Instant.now(); + + // 设立(重设)对应pod的定时删除任务(这个时间必须大于${timeLimit},确保脚本执行期间pod不会中途死) 单位:秒 + int timeLimit = buildParams.getInteger("timeLimit"); + gameService.reTiming(type + "-" + tpiID, timeLimit + 60); + + // 查询 pod + Pod pod = k8sService.getK8sRunningPod(podInLabels, podNotInLabels); + // 如果pod不存在,还将创建 + pod = runPodService.createRunPod(pod, buildParams, tpiID, type, timeLimit); + + final PodRef podRef = new PodRef(); + if (pod != null) { + podRef.setPod(pod); + String podName = pod.getMetadata().getName(); + + double createPodAndSvcCost = (double) Duration.between(podStartInstant, Instant.now()).toMillis() + / 1000; + podRef.setCreatePodAndSvcCost(createPodAndSvcCost); + + // 设立(重设)对应pod的定时删除任务(这个时间必须大于${timeLimit},确保脚本执行期间pod不会中途死) 单位:秒 + gameService.reTiming(podName, timeLimit + 60); + } + + JSONArray cases = JSONArray.parseArray(testCases); + if (podRef.getPod() == null) { + logger.error("实训 {} 创建 pod 失败", tpiID); + String msg = GameHelper.getResult("系统繁忙,请稍后重试", cases.size(), BuildResultCsts.DOWNLOAD_STATUS_SUCCESS, + BuildResultCsts.CREATE_POD_STATUS_FAIL); + gameService.encapsulateBuildResult(msg, buildParams, testCases); + return; + } + + // 记录创建pod耗时 + GameHelper.setTimeCostInJedis("timeCost:" + tpiID + ":" + buildID, "createPod", + String.format("%.3f", podRef.getCreatePodAndSvcCost())); + + out = GameHelper.getTextMsgResult("服务启动完成"); + gameService.encapsulateStepByStepResult(out, buildParams, testCases); + + // 在pod中执行评测脚本 + Integer executeTimeLimit = buildParams.getInteger("executeTime") == null ? buildParams.getInteger("timeLimit") + : buildParams.getInteger("executeTime"); + kubernetesService.executeShellInPod(buildParams, podRef.getPod(), buildParams.getInteger("needPortMapping"), + executeTimeLimit, buildParams.getInteger("isPublished"), buildParams.getInteger("instanceChallenge"), + buildParams.getString("testCases"), Boolean.TRUE); + + } + + @Override + public String toString() { + return "singleEvaThread{" + buildParams.toJSONString() + '}'; + } +} diff --git a/src/main/java/com/educoder/bridge/k8s/controller/ScriptController.java b/src/main/java/com/educoder/bridge/k8s/controller/ScriptController.java new file mode 100644 index 0000000..b2a2685 --- /dev/null +++ b/src/main/java/com/educoder/bridge/k8s/controller/ScriptController.java @@ -0,0 +1,66 @@ +package com.educoder.bridge.k8s.controller; + +import com.alibaba.fastjson.JSONObject; +import com.educoder.bridge.common.constant.ApiResultCodeCsts; +import com.educoder.bridge.common.model.ApiResult; +import com.educoder.bridge.common.model.BridgePage; +import com.educoder.bridge.game.service.K8sService; +import com.educoder.bridge.k8s.model.BridgePod; +import com.educoder.bridge.k8s.model.EvaluatingScript; +import com.educoder.bridge.k8s.model.PodQueryParam; +import com.educoder.bridge.k8s.service.BridgePodService; +import com.educoder.bridge.k8s.service.EvaScriptService; +import com.github.pagehelper.Page; +import io.fabric8.kubernetes.api.model.Pod; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.commons.lang.StringEscapeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 评测脚本相关的接口 + */ +@Api(value = "script", hidden = true) +@RestController +@RequestMapping("/script") +public class ScriptController { + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private EvaScriptService evaScriptService; + + /** + * 设置评测脚本 + */ + @RequestMapping(path = "/set", method = RequestMethod.POST) + @ApiOperation(value = "设置评测脚本", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public JSONObject set( + @ApiParam(name = "scriptType", required = true, value = "脚本类型") @RequestParam("scriptType") String scriptType, + @ApiParam(name = "script", required = true, value = "脚本") @RequestParam("script") String script + ) throws Exception { + logger.info("[start]设置评测脚本, type: {}, script: {}", scriptType, script); + JSONObject response = new JSONObject(); + + LocalDateTime now = LocalDateTime.now(); + EvaluatingScript evaluatingScript = new EvaluatingScript(); + evaluatingScript.setScriptType(scriptType); + evaluatingScript.setScript(script); + evaluatingScript.setCreateTime(now); + evaluatingScript.setUpdateTime(now); + + evaScriptService.savaEvaluationScript(evaluatingScript); + + response.put("code", 0); + response.put("msg", "设置评测脚本成功"); + logger.info("[end]获取Pod列表"); + return response; + } +} diff --git a/src/main/java/com/educoder/bridge/k8s/dao/EvaScriptMapper.java b/src/main/java/com/educoder/bridge/k8s/dao/EvaScriptMapper.java new file mode 100644 index 0000000..15a0168 --- /dev/null +++ b/src/main/java/com/educoder/bridge/k8s/dao/EvaScriptMapper.java @@ -0,0 +1,17 @@ +package com.educoder.bridge.k8s.dao; + +import com.educoder.bridge.k8s.model.EvaluatingScript; + +public interface EvaScriptMapper { + int deleteByPrimaryKey(Long id); + + int insert(EvaluatingScript record); + + int insertSelective(EvaluatingScript record); + + EvaluatingScript selectByPrimaryKey(Long id); + + int updateByPrimaryKey(EvaluatingScript record); + + String selectScriptByType(String scriptType); +} \ No newline at end of file diff --git a/src/main/java/com/educoder/bridge/k8s/model/EvaluatingScript.java b/src/main/java/com/educoder/bridge/k8s/model/EvaluatingScript.java new file mode 100644 index 0000000..ea54020 --- /dev/null +++ b/src/main/java/com/educoder/bridge/k8s/model/EvaluatingScript.java @@ -0,0 +1,66 @@ +package com.educoder.bridge.k8s.model; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.time.LocalDateTime; + +/** + * 单个文件评测脚本 + */ +@ApiModel(value = "evaluating_script", description = "单个文件评测脚本") +public class EvaluatingScript { + + @ApiModelProperty(value = "脚本ID") + private long id; + + @ApiModelProperty(value = "脚本类型") + private String scriptType; + + @ApiModelProperty(value = "脚本") + private String script; + + private LocalDateTime createTime; + + private LocalDateTime updateTime; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getScriptType() { + return scriptType; + } + + public void setScriptType(String scriptType) { + this.scriptType = scriptType; + } + + public String getScript() { + return script; + } + + public void setScript(String script) { + this.script = script; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } +} diff --git a/src/main/java/com/educoder/bridge/k8s/service/EvaScriptService.java b/src/main/java/com/educoder/bridge/k8s/service/EvaScriptService.java new file mode 100644 index 0000000..e1e1674 --- /dev/null +++ b/src/main/java/com/educoder/bridge/k8s/service/EvaScriptService.java @@ -0,0 +1,28 @@ +package com.educoder.bridge.k8s.service; + +import com.educoder.bridge.k8s.dao.EvaScriptMapper; +import com.educoder.bridge.k8s.model.EvaluatingScript; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * Created by macbookpro on 2019/8/13. + */ +@Service("evaScriptService") +public class EvaScriptService { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private EvaScriptMapper evaScriptMapper; + + public void savaEvaluationScript(EvaluatingScript evaluatingScript) { + evaScriptMapper.insert(evaluatingScript); + } + + public String getScriptByType(String evaScriptType) { + return evaScriptMapper.selectScriptByType(evaScriptType); + } +} diff --git a/src/main/resources/config_testeduplus_ali.properties b/src/main/resources/config_testeduplus_ali.properties index c11f48e..3002180 100644 --- a/src/main/resources/config_testeduplus_ali.properties +++ b/src/main/resources/config_testeduplus_ali.properties @@ -74,4 +74,6 @@ dbpool.minIdle=100 vncPort=6901 #kafka -bootstrapServersConfig=172.16.94.173:9092 \ No newline at end of file +bootstrapServersConfig=172.16.94.173:9092 + +singleEvaCodePath=code/src/step \ No newline at end of file diff --git a/src/main/resources/mapper/k8s/EvaScriptMapper.xml b/src/main/resources/mapper/k8s/EvaScriptMapper.xml new file mode 100644 index 0000000..04b056f --- /dev/null +++ b/src/main/resources/mapper/k8s/EvaScriptMapper.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + id, script_type, script, create_time, update_time + + + + delete from + evaluating_script + where id = #{id,jdbcType=BIGINT} + + + insert into evaluating_script (id, script_type, script, + create_time, + update_time) + values (#{id,jdbcType=BIGINT}, #{scriptType,jdbcType=VARCHAR}, + #{script,jdbcType=VARCHAR}, + #{createTime,jdbcType=TIMESTAMP}, + #{updateTime,jdbcType=TIMESTAMP}) + + + insert into evaluating_script + + + id, + + + script_type, + + + script, + + + create_time, + + + update_time, + + + + + #{id,jdbcType=BIGINT}, + + + #{scriptType,jdbcType=VARCHAR}, + + + #{script,jdbcType=VARCHAR}, + + + #{createTime,jdbcType=TIMESTAMP}, + + + #{updateTime,jdbcType=TIMESTAMP}, + + + + + update evaluating_script + + + script_type = #{scriptType,jdbcType=VARCHAR}, + + + script = #{script,jdbcType=VARCHAR}, + + + create_time = #{createTime,jdbcType=TIMESTAMP}, + + + update_time = #{updateTime,jdbcType=TIMESTAMP}, + + + where id = #{id,jdbcType=BIGINT} + + + update evaluating_script + set script_type = #{scriptType,jdbcType=VARCHAR}, + script = #{script,jdbcType=VARCHAR}, + create_time = + #{createTime,jdbcType=TIMESTAMP}, + update_time = + #{updateTime,jdbcType=TIMESTAMP} + where id = #{id,jdbcType=BIGINT} + + + + + + + \ No newline at end of file