Просмотр исходного кода

增加日志解析后持久化保存功能

Miaomz 4 лет назад
Родитель
Сommit
753c2a5ee9

+ 3 - 3
src/main/java/com/seecoder/dataanalysis/logic/parser/LogParsingService.java

@@ -13,7 +13,7 @@ public interface LogParsingService {
      * @param log json格式的日志
      * @return SimpleLog,包含日志的元数据以及json格式的日志data
      */
-    SimpleLog parseLog(String log);
+    SimpleLog parseLog(String log) throws ParsingException;
 
     /**
      * 基于日志元数据(opType),解析日志的data,并返回对应实体。如果不使用范型,则返回Object类型
@@ -21,13 +21,13 @@ public interface LogParsingService {
      * @param save 是否持久化保存
      * @return 日志操作类型对应的数据实体
      */
-    <T> T parseLogData(SimpleLog simpleLog, boolean save);
+    <T> T parseLogData(SimpleLog simpleLog, boolean save) throws ParsingException;
 
     /**
      * 基于日志元数据,返回对应的持久化实体entity的类名
      * @param opType 操作类型
      * @return entity的classname
      */
-    String parseOpType(int opType);
+    String parseOpType(int opType) throws ParsingException;
 
 }

+ 20 - 0
src/main/java/com/seecoder/dataanalysis/logic/parser/ParsingException.java

@@ -0,0 +1,20 @@
+package com.seecoder.dataanalysis.logic.parser;
+
+/**
+ * @author miaomuzhi
+ * @since 2022/2/15
+ */
+public class ParsingException extends Exception{
+    /**
+     * 解析错误码
+     * 0: 元日志格式错误
+     * 1:日志格式错误
+     * 2:不支持的日志操作码
+     */
+    private int errorCode;
+
+    public ParsingException(String message, int errorCode) {
+        super(message);
+        this.errorCode = errorCode;
+    }
+}

+ 54 - 0
src/main/java/com/seecoder/dataanalysis/logic/parser/convertor/LogConvertor.java

@@ -0,0 +1,54 @@
+package com.seecoder.dataanalysis.logic.parser.convertor;
+
+import com.seecoder.dataanalysis.data.entity.eval.EvalExamInfo;
+import com.seecoder.dataanalysis.data.entity.eval.EvalExamRecord;
+import com.seecoder.dataanalysis.vo.AnswerDTO;
+import com.seecoder.dataanalysis.vo.EvalExamInfoDTO;
+import com.seecoder.dataanalysis.vo.EvalExamRecordDTO;
+import org.springframework.beans.BeanUtils;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @author miaomuzhi
+ * @since 2022/2/15
+ */
+public class LogConvertor {
+
+    public static EvalExamRecord convertToEvalExamRecordEntity(EvalExamRecordDTO evalExamRecordDTO){
+        if (evalExamRecordDTO == null) {
+            return null;
+        }
+
+        EvalExamRecord record = new EvalExamRecord();
+        BeanUtils.copyProperties(evalExamRecordDTO, record);
+        record.setErrorQuestions(new HashMap<>());
+
+        List<AnswerDTO> answers = evalExamRecordDTO.getErrorQuestions();
+        if (answers != null) {
+            for (AnswerDTO answer : answers) {
+                record.getErrorQuestions().put(answer.getQuestionId(), answer.getQuestionScore());
+            }
+        }
+        return record;
+    }
+
+    public static EvalExamInfo convertToEvalExamInfoEntity(EvalExamInfoDTO evalExamInfoDTO){
+        if (evalExamInfoDTO == null) {
+            return null;
+        }
+
+        EvalExamInfo info = new EvalExamInfo();
+        BeanUtils.copyProperties(evalExamInfoDTO, info);
+        info.setQuestionAndScore(new HashMap<>());
+
+        List<AnswerDTO> answers = evalExamInfoDTO.getQuestionAndScore();
+        if (answers != null) {
+            for (AnswerDTO answer : answers) {
+                info.getQuestionAndScore().put(answer.getQuestionId(), answer.getQuestionScore());
+            }
+        }
+        return info;
+    }
+}

+ 44 - 6
src/main/java/com/seecoder/dataanalysis/logic/parser/impl/LogParsingServiceImpl.java

@@ -1,11 +1,18 @@
 package com.seecoder.dataanalysis.logic.parser.impl;
 
 import com.alibaba.fastjson.JSONException;
+import com.seecoder.dataanalysis.data.dao.eval.EvalExamInfoDao;
+import com.seecoder.dataanalysis.data.dao.eval.EvalExamRecordDao;
+import com.seecoder.dataanalysis.data.entity.eval.EvalExamInfo;
+import com.seecoder.dataanalysis.data.entity.eval.EvalExamRecord;
 import com.seecoder.dataanalysis.logic.parser.LogParsingService;
+import com.seecoder.dataanalysis.logic.parser.ParsingException;
+import com.seecoder.dataanalysis.logic.parser.convertor.LogConvertor;
 import com.seecoder.dataanalysis.util.JsonUtil;
 import com.seecoder.dataanalysis.vo.EvalExamInfoDTO;
 import com.seecoder.dataanalysis.vo.EvalExamRecordDTO;
 import com.seecoder.dataanalysis.vo.SimpleLog;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
@@ -24,34 +31,65 @@ public class LogParsingServiceImpl implements LogParsingService {
      */
     private Map<Integer, String> opTypesTable;
 
+    private EvalExamRecordDao evalExamRecordDao;
+
+    private EvalExamInfoDao evalExamInfoDao;
+
+    @Autowired
+    public void setEvalExamRecordDao(EvalExamRecordDao evalExamRecordDao) {
+        this.evalExamRecordDao = evalExamRecordDao;
+    }
+
+    @Autowired
+    public void setEvalExamInfoDao(EvalExamInfoDao evalExamInfoDao) {
+        this.evalExamInfoDao = evalExamInfoDao;
+    }
+
+
     @Override
-    public SimpleLog parseLog(String log) {
+    public SimpleLog parseLog(String log) throws ParsingException{
         try {
             return JsonUtil.toObject(log, SimpleLog.class);
         } catch (JSONException e) {
             e.printStackTrace();
-            return null;
+            throw new ParsingException(e.toString(), 0);
         }
     }
 
     @Override
     @SuppressWarnings("unchecked")
-    public <T> T parseLogData(SimpleLog simpleLog, boolean save) {
+    public <T> T parseLogData(SimpleLog simpleLog, boolean save) throws ParsingException{
         try {
             String className = parseOpType(simpleLog.getOpType());
             Class clazz = Class.forName(className);
             Object data = JsonUtil.toObject(simpleLog.getData(), clazz);
 
-            //TODO save into the database
+            if (!save) {
+                return (T) data;
+            }
+
+            if (className.equals(EvalExamInfoDTO.class.getName())) {
+                EvalExamInfo info = LogConvertor.convertToEvalExamInfoEntity((EvalExamInfoDTO) data);
+                evalExamInfoDao.save(info);
+            } else if (className.equals(EvalExamRecordDTO.class.getName())) {
+                EvalExamRecord record = LogConvertor.convertToEvalExamRecordEntity((EvalExamRecordDTO) data);
+                evalExamRecordDao.save(record);
+            }
             return (T) data;
-        } catch (ClassNotFoundException e){
+        } catch (ClassNotFoundException|ClassCastException e){
             e.printStackTrace();
             return null;
+        }  catch (JSONException e) {
+            e.printStackTrace();
+            throw new ParsingException(e.toString(), 1);
         }
     }
 
     @Override
-    public String parseOpType(int opType) {
+    public String parseOpType(int opType) throws ParsingException {
+        if (!opTypesTable.containsKey(opType)) {
+            throw new ParsingException("不支持的操作类型:" + opType, 2);
+        }
         return opTypesTable.get(opType);
     }
 

+ 4 - 0
src/main/java/com/seecoder/dataanalysis/vo/AnswerDTO.java

@@ -1,13 +1,17 @@
 package com.seecoder.dataanalysis.vo;
 
 import com.alibaba.fastjson.annotation.JSONField;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 /**
  * @author miaomuzhi
  * @since 2022/2/6
  */
 @Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class AnswerDTO {
 
     @JSONField(name = "question_id")

+ 4 - 0
src/main/java/com/seecoder/dataanalysis/vo/EvalExamInfoDTO.java

@@ -1,7 +1,9 @@
 package com.seecoder.dataanalysis.vo;
 
 import com.alibaba.fastjson.annotation.JSONField;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.Date;
 import java.util.List;
@@ -11,6 +13,8 @@ import java.util.List;
  * @since 2022/2/6
  */
 @Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class EvalExamInfoDTO {
 
     /**

+ 4 - 0
src/main/java/com/seecoder/dataanalysis/vo/EvalExamRecordDTO.java

@@ -1,7 +1,9 @@
 package com.seecoder.dataanalysis.vo;
 
 import com.alibaba.fastjson.annotation.JSONField;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.Date;
 import java.util.List;
@@ -11,6 +13,8 @@ import java.util.List;
  * @since 2022/2/6
  */
 @Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class EvalExamRecordDTO {
 
     /**

+ 33 - 0
src/test/java/com/seecoder/dataanalysis/logic/parser/convertor/LogConvertorTest.java

@@ -0,0 +1,33 @@
+package com.seecoder.dataanalysis.logic.parser.convertor;
+
+import com.seecoder.dataanalysis.data.entity.eval.EvalExamInfo;
+import com.seecoder.dataanalysis.data.entity.eval.EvalExamRecord;
+import com.seecoder.dataanalysis.vo.AnswerDTO;
+import com.seecoder.dataanalysis.vo.EvalExamInfoDTO;
+import com.seecoder.dataanalysis.vo.EvalExamRecordDTO;
+import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author miaomuzhi
+ * @since 2022/2/15
+ */
+class LogConvertorTest {
+
+    @Test
+    public void testConvertToEvalExamRecordEntity(){
+        EvalExamRecord record = LogConvertor.convertToEvalExamRecordEntity(new EvalExamRecordDTO(1,1,null, 0.1, null));
+        assertEquals(1, record.getExamId());
+        assertEquals(0, record.getErrorQuestions().size());
+    }
+
+    @Test
+    public void testConvertToEvalExamInfoEntity(){
+        EvalExamInfoDTO infoDTO = new EvalExamInfoDTO();
+        infoDTO.setQuestionAndScore(Lists.newArrayList(new AnswerDTO("123", 321), new AnswerDTO("aa", 100)));
+        EvalExamInfo info = LogConvertor.convertToEvalExamInfoEntity(infoDTO);
+        assertEquals(2, info.getQuestionAndScore().size());
+    }
+}

+ 16 - 6
src/test/java/com/seecoder/dataanalysis/logic/parser/impl/LogParsingServiceImplTest.java

@@ -1,5 +1,6 @@
 package com.seecoder.dataanalysis.logic.parser.impl;
 
+import com.seecoder.dataanalysis.logic.parser.ParsingException;
 import com.seecoder.dataanalysis.util.FileUtil;
 import com.seecoder.dataanalysis.vo.EvalExamInfoDTO;
 import com.seecoder.dataanalysis.vo.SimpleLog;
@@ -28,8 +29,13 @@ class LogParsingServiceImplTest {
     }
 
     @Test
-    void parseLog() {
-        assertNull(parsingService.parseLog("dsaf"));
+    void parseLog() throws ParsingException{
+        try {
+            parsingService.parseLog("dsaf");
+        } catch (Exception e) {
+            assertEquals(ParsingException.class.getName(), e.getClass().getName());
+        }
+
         String logContent = FileUtil.readFile(getClass().getResource("/sample_logs/gen0.log").getFile());
         SimpleLog simpleLog = parsingService.parseLog(logContent);
         assertEquals(0, simpleLog.getOpType());
@@ -37,7 +43,7 @@ class LogParsingServiceImplTest {
     }
 
     @Test
-    void parseLogData() {
+    void parseLogData() throws ParsingException {
         String logContent = FileUtil.readFile(getClass().getResource("/sample_logs/gen0.log").getFile());
         SimpleLog simpleLog = parsingService.parseLog(logContent);
         Object o = parsingService.parseLogData(simpleLog, false);
@@ -47,8 +53,12 @@ class LogParsingServiceImplTest {
     }
 
     @Test
-    void parseOpType() {
-        assertEquals("com.seecoder.dataanalysis.data.entity.eval.EvalExamInfo", parsingService.parseOpType(0));
-        assertNull(parsingService.parseOpType(-1));
+    void parseOpType() throws ParsingException {
+        assertEquals("com.seecoder.dataanalysis.vo.EvalExamInfoDTO", parsingService.parseOpType(0));
+        try {
+            parsingService.parseOpType(-1);
+        } catch (Exception e) {
+            assertEquals(ParsingException.class.getName(), e.getClass().getName());
+        }
     }
 }