|
|
@@ -0,0 +1,100 @@
|
|
|
+package nju.seec.SEECdemo.logic.service.impl.assignment;
|
|
|
+
|
|
|
+import nju.seec.SEECdemo.data.dao.assignment.CodeDAO;
|
|
|
+import nju.seec.SEECdemo.data.dao.assignment.CodeResultDAO;
|
|
|
+import nju.seec.SEECdemo.data.entity.assignment.Code;
|
|
|
+import nju.seec.SEECdemo.data.entity.assignment.CodeResult;
|
|
|
+import nju.seec.SEECdemo.data.entity.Group;
|
|
|
+import nju.seec.SEECdemo.logic.api.GitlabApi;
|
|
|
+import nju.seec.SEECdemo.logic.api.JenkinsApi;
|
|
|
+import nju.seec.SEECdemo.logic.storage.StorageProvider;
|
|
|
+import nju.seec.SEECdemo.util.enums.AssignmentStatus;
|
|
|
+import org.apache.commons.io.FileUtils;
|
|
|
+import org.eclipse.jgit.api.errors.GitAPIException;
|
|
|
+import org.gitlab4j.api.GitLabApiException;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.zeroturnaround.zip.ZipUtil;
|
|
|
+
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+@Component
|
|
|
+public class AssignmentPaperBuilder {
|
|
|
+
|
|
|
+ private static final String TEMP_PREFIX = "MOOCODER-PAPER-";
|
|
|
+ private final GitlabApi gitlabApi;
|
|
|
+ private final GitHelper helper;
|
|
|
+ private final JenkinsApi jenkinsApi;
|
|
|
+ private final CodeDAO codeDAO;
|
|
|
+ private final CodeResultDAO codeResultDAO;
|
|
|
+ private final StorageProvider storageProvider;
|
|
|
+
|
|
|
+ private final QuestionServiceStub questionServiceStub;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public AssignmentPaperBuilder(GitlabApi gitlabApi, GitHelper helper, JenkinsApi jenkinsApi, CodeDAO codeDAO, CodeResultDAO codeResultDAO, StorageProvider storageProvider,
|
|
|
+ QuestionServiceStub questionServiceStub){
|
|
|
+ this.gitlabApi = gitlabApi;
|
|
|
+ this.helper = helper;
|
|
|
+ this.jenkinsApi = jenkinsApi;
|
|
|
+ this.codeDAO = codeDAO;
|
|
|
+ this.codeResultDAO = codeResultDAO;
|
|
|
+ this.storageProvider = storageProvider;
|
|
|
+ this.questionServiceStub = questionServiceStub;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ public void buildCodePaper(int codeId) throws IOException, GitLabApiException, GitAPIException {
|
|
|
+ Code code = codeDAO.findById(codeId);
|
|
|
+ if (code.getStatus() != AssignmentStatus.PREPARING) return;
|
|
|
+ File tempDir = Files.createTempDirectory(TEMP_PREFIX).toFile();
|
|
|
+ try {
|
|
|
+ releaseQuestion(code.getQuestionId(), tempDir);
|
|
|
+ code.setInitHash(helper.push(tempDir, code.getUuid()));
|
|
|
+ // 为群组创建项目,并将组员加入到项目中
|
|
|
+ for(Group group:code.getCourse().getGroupSet()){
|
|
|
+ int projectId = gitlabApi.forkProject(group.getMemberSet().iterator().next().getId(), code.getId(), group.getNamespace());
|
|
|
+ CodeResult codeResult = new CodeResult();
|
|
|
+ codeResult.setId(projectId);
|
|
|
+ codeResult.setGroup(group);
|
|
|
+ codeResult.setCode(code);
|
|
|
+ // TODO
|
|
|
+ // 创建jenkins上的构建job
|
|
|
+ String buildJob = group.getName() + "-" + projectId + "-build";
|
|
|
+ jenkinsApi.createBuildJob(buildJob);
|
|
|
+ codeResult.setBuildJob(buildJob);
|
|
|
+ // 调用kube Api创建该项目的应用空间,并记录其id
|
|
|
+
|
|
|
+ // 创建jenkins上的测试job
|
|
|
+ String testJob = group.getName() + "-" + projectId + "-test";
|
|
|
+ jenkinsApi.createTestJob(testJob);
|
|
|
+ codeResult.setTestJob(testJob);
|
|
|
+ codeResultDAO.save(codeResult);
|
|
|
+ }
|
|
|
+ code.setStatus(AssignmentStatus.AVAILABLE);
|
|
|
+ } catch (Exception e) {
|
|
|
+ code.setStatus(AssignmentStatus.UNAVAILABLE);
|
|
|
+ throw e;
|
|
|
+ } finally {
|
|
|
+ codeDAO.save(code);
|
|
|
+ FileUtils.deleteDirectory(tempDir);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void releaseQuestion(int questionId, File codeDir) throws IOException {
|
|
|
+ FileUtils.cleanDirectory(codeDir);
|
|
|
+ String problemName = questionServiceStub.getQuestionUniqueName(questionId);
|
|
|
+ byte[] content = storageProvider.fetch(problemName + ".zip");
|
|
|
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(content);
|
|
|
+ ZipUtil.unpack(inputStream, codeDir);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|