Browse Source

feat: rabbitmq

haha 4 years ago
parent
commit
53501d45f5

+ 5 - 11
seec-oj-server/pom.xml

@@ -32,17 +32,6 @@
             <artifactId>spring-boot-configuration-processor</artifactId>
             <optional>true</optional>
         </dependency>
-<!--        <dependency>-->
-<!--            <groupId>cn.seecoder</groupId>-->
-<!--            <artifactId>codejudge-client</artifactId>-->
-<!--            <version>0.2.0</version>-->
-<!--            <exclusions>-->
-<!--                <exclusion>-->
-<!--                    <groupId>org.apache.logging.log4j</groupId>-->
-<!--                    <artifactId>log4j-slf4j-impl</artifactId>-->
-<!--                </exclusion>-->
-<!--            </exclusions>-->
-<!--        </dependency>-->
         <dependency>
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-core</artifactId>
@@ -105,6 +94,11 @@
             <version>1.2.62</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 4 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/config/RabbitMQConfig.java

@@ -0,0 +1,4 @@
+package cn.seecoder.ojserver.config;
+
+public class RabbitMQConfig {
+}

+ 5 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/controller/JudgeController.java

@@ -42,6 +42,11 @@ public class JudgeController {
         }
     }
 
+    @PostMapping("/asyncCode")
+    public Response asyncJudgeCode(@RequestParam(value = "problemId") Integer problemId, @RequestBody CodeJudgeVO codeJudgeVO){
+        return Response.buildSuccess(judgeService.asyncJudgeCode(problemId, codeJudgeVO));
+    }
+
 
 
 }

+ 8 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/dao/CommitDAO.java

@@ -0,0 +1,8 @@
+package cn.seecoder.ojserver.dao;
+
+import cn.seecoder.ojserver.dao.entity.Commit;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface CommitDAO extends JpaRepository<Commit,Integer> {
+
+}

+ 0 - 2
seec-oj-server/src/main/java/cn/seecoder/ojserver/dao/ProblemDAO.java

@@ -1,11 +1,9 @@
 package cn.seecoder.ojserver.dao;
 
 import cn.seecoder.ojserver.dao.entity.Problem;
-import cn.seecoder.ojserver.model.dto.ProblemDTO;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 
-import javax.persistence.PersistenceContext;
 import java.util.List;
 import java.util.Map;
 

+ 49 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/dao/entity/Commit.java

@@ -0,0 +1,49 @@
+package cn.seecoder.ojserver.dao.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Data
+@Entity
+@Table(name = "commit")
+public class Commit {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private Integer id;
+
+    @Basic
+    @Column(name = "user_id")
+    private Integer userId;
+
+    @Basic
+    @Column(name = "result")
+    private String result;
+
+    @Basic
+    @Column(name = "code")
+    private String code;
+
+    @Basic
+    @Column(name = "language")
+    private String language;
+
+    @Basic
+    @Column(name = "problem_id")
+    private Integer problemId;
+
+    @Basic
+    @Column(name = "score")
+    private Integer score;
+
+    @Basic
+    @Column(name = "commit_time")
+    private Date commitTime;
+
+    @Basic
+    @Column(name = "judge_time")
+    private Date judgeTime;
+
+}

+ 58 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/enums/CodeJudgeResultType.java

@@ -0,0 +1,58 @@
+package cn.seecoder.ojserver.enums;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * @author mars
+ */
+
+public enum CodeJudgeResultType {
+    /**
+     * 正确
+     */
+    @JsonProperty("Accepted")
+    ACCEPT,
+    /**
+     * 输出答案格式出错
+     */
+    @JsonProperty("Presentation Error")
+    PRESENTATION_ERROR,
+    /**
+     * 超时
+     */
+    @JsonProperty("Time Limit Exceeded")
+    TIME_LIMIT_EXCEEDED,
+    /**
+     * 超出空间限制
+     */
+    @JsonProperty("Memory Limit Exceeded")
+    MEMORY_LIMIT_EXCEEDED,
+    /**
+     * 错误答案
+     */
+    @JsonProperty("Wrong Answer")
+    WRONG_ANSWER,
+    /**
+     * 运行错误
+     */
+    @JsonProperty("Runtime Error")
+    RUNTIME_ERROR,
+    /**
+     * 输出超过限制
+     */
+    @JsonProperty("Output Limit Exceeded")
+    OUTPUT_LIMIT_EXCEEDED,
+    /**
+     * 编译错误
+     */
+    @JsonProperty("Compile Error")
+    COMPILE_ERROR,
+    /**
+     * 系统错误
+     */
+    @JsonProperty("System Error")
+    SYSTEM_ERROR;
+
+    private CodeJudgeResultType() {
+    }
+}

+ 17 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/model/dto/CodeJudgeDTO.java

@@ -0,0 +1,17 @@
+package cn.seecoder.ojserver.model.dto;
+
+import cn.seecoder.ojserver.model.vo.CodeJudgeVO;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CodeJudgeDTO implements Serializable {
+    private Integer commitId;
+    private Integer problemId;
+    private CodeJudgeVO codeJudgeVO;
+}

+ 0 - 23
seec-oj-server/src/main/java/cn/seecoder/ojserver/model/dto/ProblemDTO.java

@@ -1,23 +0,0 @@
-package cn.seecoder.ojserver.model.dto;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-import javax.persistence.*;
-
-@Data
-@Entity
-@Getter
-@NoArgsConstructor
-@AllArgsConstructor
-public class ProblemDTO {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Integer id;
-
-    private String name;
-
-
-}

+ 62 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/rabbitmq/RabbitMQConsumer.java

@@ -0,0 +1,62 @@
+package cn.seecoder.ojserver.rabbitmq;
+
+import cn.seecoder.codejudge.client.CodeJudgeException;
+import cn.seecoder.codejudge.client.JudgeResult;
+import cn.seecoder.codejudge.client.JudgeResultType;
+import cn.seecoder.ojserver.dao.CommitDAO;
+import cn.seecoder.ojserver.dao.entity.Commit;
+import cn.seecoder.ojserver.enums.CodeJudgeResultType;
+import cn.seecoder.ojserver.model.dto.CodeJudgeDTO;
+import cn.seecoder.ojserver.service.JudgeService;
+import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.Optional;
+
+@Component
+public class RabbitMQConsumer {
+    private final JudgeService judgeService;
+    private final CommitDAO commitDAO;
+
+    public RabbitMQConsumer(JudgeService judgeService, CommitDAO commitDAO) {
+        this.judgeService = judgeService;
+        this.commitDAO = commitDAO;
+    }
+
+    @RabbitHandler
+    @RabbitListener(queuesToDeclare = @Queue("notice_queue"))
+    public void process(CodeJudgeDTO codeJudgeDTO) {
+        JudgeResult judgeResult = judgeService.judgeCode(codeJudgeDTO.getProblemId(), codeJudgeDTO.getCodeJudgeVO());
+        CodeJudgeResultType message = CodeJudgeResultType.values()[JudgeResultType.ACCEPT.ordinal()];
+        for (JudgeResult.Item item : judgeResult.getResultList()) {
+            if (item.getResult() != JudgeResultType.ACCEPT) {
+                message = CodeJudgeResultType.values()[item.getResult().ordinal()];
+                break;
+            }
+        }
+
+        int acNum = 0;
+        for (JudgeResult.Item item : judgeResult.getResultList()) {
+            if (item.getResult() == JudgeResultType.ACCEPT) {
+                acNum++;
+            }
+        }
+
+        int score = (acNum / judgeResult.getResultList().size())*100;
+
+        Optional<Commit> optionalCommit = commitDAO.findById(codeJudgeDTO.getCommitId());
+        if(optionalCommit.isPresent()){
+            Commit commit = optionalCommit.get();
+            commit.setResult(message.name());
+            commit.setScore(score);
+            commit.setJudgeTime(new Date());
+            commitDAO.save(commit);
+        }else{
+            throw new CodeJudgeException("找不到commit",103);
+        }
+
+    }
+}

+ 1 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/service/JudgeService.java

@@ -5,4 +5,5 @@ import cn.seecoder.ojserver.model.vo.CodeJudgeVO;
 
 public interface JudgeService {
     public JudgeResult judgeCode(Integer questionId, CodeJudgeVO codeJudgeVO);
+    public JudgeResult asyncJudgeCode(Integer questionId, CodeJudgeVO codeJudgeVO);
 }

+ 0 - 2
seec-oj-server/src/main/java/cn/seecoder/ojserver/service/ProblemService.java

@@ -1,8 +1,6 @@
 package cn.seecoder.ojserver.service;
 
 import cn.seecoder.ojserver.dao.entity.Problem;
-import cn.seecoder.ojserver.dao.entity.TestCase;
-import cn.seecoder.ojserver.model.dto.ProblemDTO;
 import cn.seecoder.ojserver.model.vo.ProblemVO;
 import cn.seecoder.ojserver.model.vo.TestCaseVO;
 

+ 25 - 1
seec-oj-server/src/main/java/cn/seecoder/ojserver/service/impl/JudgeServiceImpl.java

@@ -2,11 +2,14 @@ package cn.seecoder.ojserver.service.impl;
 
 import cn.seecoder.codejudge.client.JudgeDTO;
 import cn.seecoder.codejudge.client.JudgeResult;
+import cn.seecoder.ojserver.dao.CommitDAO;
+import cn.seecoder.ojserver.dao.entity.Commit;
 import cn.seecoder.ojserver.dao.entity.Problem;
 import cn.seecoder.ojserver.dao.entity.TestCase;
 import cn.seecoder.ojserver.exception.ThirdPartyServiceException;
 import cn.seecoder.ojserver.manager.JudgeManager;
 import cn.seecoder.ojserver.manager.QuestionManager;
+import cn.seecoder.ojserver.model.dto.CodeJudgeDTO;
 import cn.seecoder.ojserver.model.vo.CodeJudgeVO;
 import cn.seecoder.ojserver.service.JudgeService;
 
@@ -14,8 +17,10 @@ import com.nju.edu.paasMonitorClient.MonitorClient;
 import com.nju.edu.paasMonitorClient.entity.Call;
 import com.nju.edu.paasMonitorCommon.enums.SeecSystem;
 import okhttp3.*;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.stereotype.Service;
 
+import java.util.Date;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -25,8 +30,10 @@ public class JudgeServiceImpl implements JudgeService {
     private final QuestionManager questionManager;
     private final JudgeManager judgeManager;
     private final OkHttpClient client;
+    private final RabbitTemplate rabbitTemplate;
+    private final CommitDAO commitDAO;
 
-    public JudgeServiceImpl(QuestionManager questionManager, JudgeManager judgeManager) {
+    public JudgeServiceImpl(QuestionManager questionManager, JudgeManager judgeManager, RabbitTemplate rabbitTemplate, CommitDAO commitDAO) {
         this.questionManager = questionManager;
         this.judgeManager = judgeManager;
         this.client = new OkHttpClient()
@@ -34,6 +41,9 @@ public class JudgeServiceImpl implements JudgeService {
                 .connectTimeout(60000, TimeUnit.MILLISECONDS)
                 .readTimeout(60000, TimeUnit.MILLISECONDS)
                 .build();
+        this.rabbitTemplate = rabbitTemplate;
+        this.commitDAO = commitDAO;
+
     }
 
     @Override
@@ -60,5 +70,19 @@ public class JudgeServiceImpl implements JudgeService {
         }
     }
 
+    @Override
+    public JudgeResult asyncJudgeCode(Integer questionId, CodeJudgeVO codeJudgeVO) {
+        Commit commit = new Commit();
+        commit.setUserId(0);
+        commit.setProblemId(questionId);
+        commit.setCode(codeJudgeVO.getCode());
+        commit.setLanguage(codeJudgeVO.getLanguage());
+        commit.setCommitTime(new Date());
+        commitDAO.save(commit);
+        CodeJudgeDTO codeJudgeDTO = new CodeJudgeDTO(commit.getId(),questionId,codeJudgeVO);
+        rabbitTemplate.convertAndSend("notice_queue",codeJudgeDTO);
+        return null;
+    }
+
 
 }

+ 0 - 3
seec-oj-server/src/main/java/cn/seecoder/ojserver/service/impl/ProblemServiceImpl.java

@@ -6,13 +6,10 @@ import cn.seecoder.ojserver.dao.entity.TestCase;
 import cn.seecoder.ojserver.dao.TestCaseDAO;
 import cn.seecoder.ojserver.mapper.ProblemMapper;
 import cn.seecoder.ojserver.mapper.TestCaseMapper;
-import cn.seecoder.ojserver.model.dto.ProblemDTO;
 import cn.seecoder.ojserver.model.vo.ProblemVO;
 import cn.seecoder.ojserver.model.vo.TestCaseVO;
 import cn.seecoder.ojserver.service.ProblemService;
 import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.CachePut;
-import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
 import java.util.Date;

+ 5 - 0
seec-oj-server/src/main/resources/application-prod.yml

@@ -33,6 +33,11 @@ spring:
         physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
       ddl-auto: update
     show-sql: false
+  rabbitmq:
+    host: http://environment-53-203.seec.svc.cluster.local
+    port: 5672
+    username: guest
+    password: guest
 seec-bok-client:
   host: https://bok.seec.seecoder.cn
 

+ 6 - 0
seec-oj-server/src/main/resources/application-test.yml

@@ -33,6 +33,12 @@ spring:
         physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
       ddl-auto: update
     show-sql: false
+  rabbitmq:
+    host: localhost
+    port: 5672
+    username: guest
+    password: guest
+
 seec-bok-client:
   host: https://bok.seec.seecoder.cn