浏览代码

Merge branch 'mutation-rpc' into 'DEV'

Mutation rpc



See merge request !517

zhangxin 7 年之前
父节点
当前提交
90855f8cb2
共有 24 个文件被更改,包括 730 次插入21 次删除
  1. 2 3
      mooctest-site-server/pom.xml
  2. 7 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/Application.java
  3. 14 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/DownloadConstants.java
  4. 28 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/GetTargetGraphEvent.java
  5. 35 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/GetTargetGraphListener.java
  6. 1 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/MongoDBConfiguration.java
  7. 16 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/DevService.java
  8. 10 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/DevServiceImpl.java
  9. 10 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/DevServiceMockImpl.java
  10. 19 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/TargetGraphService.java
  11. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/TargetService.java
  12. 6 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromDev/AnalysisService.java
  13. 34 7
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromDev/impl/AnalysisServiceImpl.java
  14. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CalculateScoreServiceImpl.java
  15. 128 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/TargetGraphServiceImpl.java
  16. 7 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/TargetServiceImpl.java
  17. 250 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/WechatController.java
  18. 33 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/forMongo/TargetGraphDTO.java
  19. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/TargetLogic.java
  20. 7 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/APFDLogic.java
  21. 63 5
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/impl/APFDLogicImpl.java
  22. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/OSSLogicImpl.java
  23. 50 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/TargetLogicImpl.java
  24. 4 0
      mooctest-site-server/src/main/resources/application.yaml

+ 2 - 3
mooctest-site-server/pom.xml

@@ -17,11 +17,10 @@
 
 
         <dependency>
         <dependency>
             <groupId>cn.iselab.mooctest</groupId>
             <groupId>cn.iselab.mooctest</groupId>
-
             <artifactId>dev-dubbo-api</artifactId>
             <artifactId>dev-dubbo-api</artifactId>
-            <version>1.8</version>
-
+            <version>2.7.1</version>
         </dependency>
         </dependency>
+
         <dependency>
         <dependency>
             <groupId>cn.iselab.mooctest</groupId>
             <groupId>cn.iselab.mooctest</groupId>
             <artifactId>kibug-dubbo-api</artifactId>
             <artifactId>kibug-dubbo-api</artifactId>

+ 7 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/Application.java

@@ -1,5 +1,11 @@
 package cn.iselab.mooctest.site;
 package cn.iselab.mooctest.site;
 
 
+import cn.iselab.mooctest.site.configure.ApplicationStartup;
+import cn.iselab.mooctest.site.service.TargetGraphService;
+import cn.iselab.mooctest.site.service.impl.TargetGraphServiceImpl;
+import cn.iselab.mooctest.site.web.data.forMongo.TargetGraphDTO;
+import com.google.gson.Gson;
+import net.sf.json.JSONObject;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration;
 import org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -111,7 +117,7 @@ public class Application {
 
 
         // To disabled web environment, change `true` to `false`
         // To disabled web environment, change `true` to `false`
         application.setWebEnvironment(true);
         application.setWebEnvironment(true);
-//        application.addListeners(new ApplicationStartup());
+        application.addListeners(new ApplicationStartup());
         application.run(args);
         application.run(args);
     }
     }
 
 

+ 14 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/DownloadConstants.java

@@ -0,0 +1,14 @@
+package cn.iselab.mooctest.site.common.constant;
+
+/**
+ * @Author ROKG
+ * @Description
+ * @Date: Created in 下午8:48 2018/1/16
+ * @Modified By:
+ */
+public class DownloadConstants {
+
+    public static String SAVE_PATH="/var/www/download/";
+
+    public static String DOWNLOAD_PATH="/download/";
+}

+ 28 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/GetTargetGraphEvent.java

@@ -0,0 +1,28 @@
+package cn.iselab.mooctest.site.common.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+
+/**
+ * @Author ROKG
+ * @Description
+ * @Date: Created in 下午5:51 2018/1/16
+ * @Modified By:
+ */
+@Getter
+@Builder
+@AllArgsConstructor
+public class GetTargetGraphEvent implements Event {
+
+    private long targetId;
+
+    private String url;
+
+    private long targetType;
+
+    @Override
+    public String getDescription() {
+        return String.format("get target graph, id: %s", targetId);
+    }
+}

+ 35 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/GetTargetGraphListener.java

@@ -0,0 +1,35 @@
+package cn.iselab.mooctest.site.common.event;
+
+import cn.iselab.mooctest.site.service.TargetService;
+import cn.iselab.mooctest.site.web.logic.TargetLogic;
+import com.google.common.eventbus.Subscribe;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author ROKG
+ * @Description
+ * @Date: Created in 下午5:49 2018/1/16
+ * @Modified By:
+ */
+@Component
+public class GetTargetGraphListener implements InitializingBean {
+
+    @Autowired
+    private EventUtil eventUtil;
+
+    @Autowired
+    private TargetLogic targetLogic;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        eventUtil.register(this);
+    }
+
+    @Subscribe
+    public void getTargetGraph(GetTargetGraphEvent event) throws Exception{
+        targetLogic.getTargetGraph(event.getTargetId(),event.getTargetType(),event.getUrl());
+    }
+
+}

+ 1 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/MongoDBConfiguration.java

@@ -24,6 +24,7 @@ public class MongoDBConfiguration {
     private String competeAnalysisCollection;
     private String competeAnalysisCollection;
     private String difficultAnalysisCollection;
     private String difficultAnalysisCollection;
     private String timeAnalysisCollection;
     private String timeAnalysisCollection;
+    private String targetGraphCollection;
     private String base64Auth;
     private String base64Auth;
 
 
 }
 }

+ 16 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/DevService.java

@@ -42,6 +42,22 @@ public interface DevService {
     public MutationDTO mutationAnalyze(String url,List<String> mutators);
     public MutationDTO mutationAnalyze(String url,List<String> mutators);
 
 
     /**
     /**
+     * get single mutation analysis result
+     * @param url
+     * @param mutators
+     * @return mutation node result
+     */
+    public NodeResultDTO mutationNodeAnalyze(String url,List<String> mutators);
+
+    /**
+     * get single mutation analysis result
+     * @param url
+     * @param mutators
+     * @return mutation node result
+     */
+    public List<CaughtNodeDTO> mutationCaughtNodeAnalyze(String url,List<String> mutators);
+
+    /**
      * start analyze all the workers' case in one exam
      * start analyze all the workers' case in one exam
      * @param examID
      * @param examID
      * @param caseID
      * @param caseID

+ 10 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/DevServiceImpl.java

@@ -40,6 +40,16 @@ public class DevServiceImpl implements DevService {
     }
     }
 
 
     @Override
     @Override
+    public NodeResultDTO mutationNodeAnalyze(String url,List<String> mutators){
+        return mutationService.staticMutationNodeAnalyze(url,mutators);
+    }
+
+    @Override
+    public List<CaughtNodeDTO> mutationCaughtNodeAnalyze(String url,List<String> mutators) {
+        return mutationService.mutationNodeAnalyze(url, mutators);
+    }
+
+    @Override
     public boolean mutationAllAnalyze(long examID, long caseID, List<Long> workerID, long endTime) {
     public boolean mutationAllAnalyze(long examID, long caseID, List<Long> workerID, long endTime) {
         return analyzeService.mutationAllAnalyze(examID, caseID, workerID, endTime);
         return analyzeService.mutationAllAnalyze(examID, caseID, workerID, endTime);
     }
     }

+ 10 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/DevServiceMockImpl.java

@@ -29,6 +29,16 @@ public class DevServiceMockImpl implements DevService {
     }
     }
 
 
     @Override
     @Override
+    public NodeResultDTO mutationNodeAnalyze(String url,List<String> mutators){
+        return null;
+    }
+
+    @Override
+    public List<CaughtNodeDTO> mutationCaughtNodeAnalyze(String url,List<String> mutators){
+        return null;
+    }
+
+    @Override
     public boolean mutationAllAnalyze(long examID, long caseID, List<Long> workerID, long endTime) {
     public boolean mutationAllAnalyze(long examID, long caseID, List<Long> workerID, long endTime) {
         return false;
         return false;
     }
     }

+ 19 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/TargetGraphService.java

@@ -0,0 +1,19 @@
+package cn.iselab.mooctest.site.service;
+
+import cn.iselab.mooctest.site.web.data.forMongo.TargetGraphDTO;
+
+
+/**
+ * @Author ROKG
+ * @Description
+ * @Date: Created in 下午5:31 2018/1/16
+ * @Modified By:
+ */
+public interface TargetGraphService {
+
+    TargetGraphDTO saveTargetGraph(TargetGraphDTO caseGraphDTO);
+
+    TargetGraphDTO getTargetGraph(Long targetId);
+
+    void saveTargetGraphJson(TargetGraphDTO dto);
+}

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/TargetService.java

@@ -33,6 +33,8 @@ public interface TargetService {
 
 
     void verifyApp(App app);
     void verifyApp(App app);
 
 
+    void rejectTarget(long targetId);
+
     void createTargetWeb(WebTarget webTarget);
     void createTargetWeb(WebTarget webTarget);
 
 
     Page<App> getAllTargets(Pageable pageable);
     Page<App> getAllTargets(Pageable pageable);

+ 6 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromDev/AnalysisService.java

@@ -3,7 +3,9 @@ package cn.iselab.mooctest.site.service.fromDev;
 import cn.iselab.mooctest.site.models.Grade;
 import cn.iselab.mooctest.site.models.Grade;
 import cn.iselab.mooctest.site.models.Weight;
 import cn.iselab.mooctest.site.models.Weight;
 import cn.iselab.mooctest.site.rpc.dev.data.ApbcDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.ApbcDTO;
+import cn.iselab.mooctest.site.rpc.dev.data.CaughtNodeDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
+import cn.iselab.mooctest.site.rpc.dev.data.NodeResultDTO;
 
 
 import java.util.List;
 import java.util.List;
 
 
@@ -23,4 +25,8 @@ public interface AnalysisService {
     ApbcDTO apfdAnalyze(long examId, long workerId, long caseId, Weight weight);
     ApbcDTO apfdAnalyze(long examId, long workerId, long caseId, Weight weight);
 
 
     List<ApbcDTO> apfdAllAnalyze(long examId, List<Long> workerIds, long caseId, Weight weight);
     List<ApbcDTO> apfdAllAnalyze(long examId, List<Long> workerIds, long caseId, Weight weight);
+
+    NodeResultDTO mutationNodeAnalyze(String url) throws Exception;
+
+    List<CaughtNodeDTO> mutationCaughtNodeAnalyze(long examId, long workerId, long caseId);
 }
 }

+ 34 - 7
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromDev/impl/AnalysisServiceImpl.java

@@ -2,14 +2,10 @@ package cn.iselab.mooctest.site.service.fromDev.impl;
 
 
 
 
 import cn.iselab.mooctest.site.dao.GradeDao;
 import cn.iselab.mooctest.site.dao.GradeDao;
-import cn.iselab.mooctest.site.models.Case;
-import cn.iselab.mooctest.site.models.Grade;
-import cn.iselab.mooctest.site.models.Task;
-import cn.iselab.mooctest.site.models.Weight;
+import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.rpc.dev.DevService;
 import cn.iselab.mooctest.site.rpc.dev.DevService;
-import cn.iselab.mooctest.site.rpc.dev.data.ApbcDTO;
-import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
-import cn.iselab.mooctest.site.rpc.dev.data.WeightDTO;
+import cn.iselab.mooctest.site.rpc.dev.data.*;
+import cn.iselab.mooctest.site.service.AppService;
 import cn.iselab.mooctest.site.service.CaseService;
 import cn.iselab.mooctest.site.service.CaseService;
 import cn.iselab.mooctest.site.service.ExamService;
 import cn.iselab.mooctest.site.service.ExamService;
 import cn.iselab.mooctest.site.service.TaskService;
 import cn.iselab.mooctest.site.service.TaskService;
@@ -40,6 +36,8 @@ public class AnalysisServiceImpl implements AnalysisService {
     ExamService examService;
     ExamService examService;
     @Autowired
     @Autowired
     TaskService taskService;
     TaskService taskService;
+    @Autowired
+    AppService appService;
 
 
     @Override
     @Override
     public MutationDTO mutationAnalyze(long examId, long workerId, long caseId){
     public MutationDTO mutationAnalyze(long examId, long workerId, long caseId){
@@ -73,6 +71,7 @@ public class AnalysisServiceImpl implements AnalysisService {
         return devService.apbcAnalyze(String.valueOf(examId),String.valueOf(workerId),casse.getName(),task.getBeginTime().getTime(),task.getEndTime().getTime(),weightDTO);
         return devService.apbcAnalyze(String.valueOf(examId),String.valueOf(workerId),casse.getName(),task.getBeginTime().getTime(),task.getEndTime().getTime(),weightDTO);
     }
     }
 
 
+    @Override
     public List<ApbcDTO> apfdAllAnalyze(long examId, List<Long> workerIds, long caseId, Weight weight){
     public List<ApbcDTO> apfdAllAnalyze(long examId, List<Long> workerIds, long caseId, Weight weight){
         List<ApbcDTO> apfdDTOs = new ArrayList<>();
         List<ApbcDTO> apfdDTOs = new ArrayList<>();
         for(Long workerId:workerIds){
         for(Long workerId:workerIds){
@@ -124,4 +123,32 @@ public class AnalysisServiceImpl implements AnalysisService {
             return re;
             return re;
         }
         }
     }
     }
+
+    @Override
+    public NodeResultDTO mutationNodeAnalyze(String url)throws Exception{
+        List<String> defaultList = new ArrayList<>();
+        defaultList.add("CONDITIONALS_BOUNDARY");
+        defaultList.add("NEGATE_CONDITIONALS");
+        defaultList.add("MATH");
+        defaultList.add("INCREMENTS");
+        defaultList.add("INVERT_NEGS");
+        defaultList.add("RETURN_VALS");
+        defaultList.add("VOID_METHOD_CALLS");
+        return devService.mutationNodeAnalyze(url.substring(50), defaultList);
+    }
+
+    @Override
+    public List<CaughtNodeDTO> mutationCaughtNodeAnalyze(long examId, long workerId, long caseId){
+        Case devCase=caseService.getCaseById(caseId);
+        String url = pluginLogic.getAnalysisSignature(examId, workerId, devCase.getName());
+        List<String> defaultList = new ArrayList<>();
+        defaultList.add("CONDITIONALS_BOUNDARY");
+        defaultList.add("NEGATE_CONDITIONALS");
+        defaultList.add("MATH");
+        defaultList.add("INCREMENTS");
+        defaultList.add("INVERT_NEGS");
+        defaultList.add("RETURN_VALS");
+        defaultList.add("VOID_METHOD_CALLS");
+        return devService.mutationCaughtNodeAnalyze(url, defaultList);
+    }
 }
 }

+ 1 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CalculateScoreServiceImpl.java

@@ -115,7 +115,7 @@ public class CalculateScoreServiceImpl implements CalculateScoreService {
         for(Double score:scores){
         for(Double score:scores){
             sum+=(score-avg)*(score-avg);
             sum+=(score-avg)*(score-avg);
         }
         }
-        result.add(Double.valueOf(decimalFormat.format(sum/(scores.size()-1))));
+        result.add(Double.valueOf(decimalFormat.format( sum / scores.size())));
         return result;
         return result;
     }
     }
 
 

+ 128 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/TargetGraphServiceImpl.java

@@ -0,0 +1,128 @@
+package cn.iselab.mooctest.site.service.impl;
+
+import cn.iselab.mooctest.site.common.constant.DownloadConstants;
+import cn.iselab.mooctest.site.configure.MongoDBConfiguration;
+import cn.iselab.mooctest.site.service.TargetGraphService;
+import cn.iselab.mooctest.site.web.data.forMongo.TargetGraphDTO;
+import cn.iselab.mooctest.site.web.util.mongodb.MongoAPIUtils;
+import com.google.gson.Gson;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+import org.apache.commons.collections.map.HashedMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+
+/**
+ * @Author ROKG
+ * @Description
+ * @Date: Created in 下午5:31 2018/1/16
+ * @Modified By:
+ */
+@Service
+public class TargetGraphServiceImpl implements TargetGraphService{
+
+    @Autowired
+    MongoDBConfiguration mongoDBConfig;
+
+
+    @Override
+    public TargetGraphDTO saveTargetGraph(TargetGraphDTO targetGraphDTO){
+        HttpHeaders headers = MongoAPIUtils.createAuthHeaderForMongo();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<TargetGraphDTO> httpEntity = new HttpEntity<>(targetGraphDTO, headers);
+        if(targetGraphDTO.getId()==null){
+            return createTargetGraph(httpEntity,targetGraphDTO);
+        }else{
+            return updateTargetGraph(httpEntity,targetGraphDTO);
+        }
+    }
+
+    @Override
+    public TargetGraphDTO getTargetGraph(Long targetId){
+        HttpHeaders headers=MongoAPIUtils.createAuthHeaderForMongo();
+        HttpEntity<String> entity=new HttpEntity<>(headers);
+
+        RestTemplate rt=new RestTemplate();
+        Map queryParams=new HashedMap();
+        queryParams.put("targetId",targetId);
+
+        String filter= MongoAPIUtils.generateFilterStr(queryParams);
+        String url=MongoAPIUtils.generateFilterUrl(mongoDBConfig.getDb(),mongoDBConfig.getTargetGraphCollection());
+        ResponseEntity<JSONObject> responseEntity=rt.exchange(url,HttpMethod.GET,entity,JSONObject.class,filter);
+        return extractTargetGraph(responseEntity);
+    }
+
+    @Override
+    public void saveTargetGraphJson(TargetGraphDTO dto){
+        JSONObject objectSC=new JSONObject();
+        objectSC.put("categories","mutation");
+        objectSC.put("nodes",dto.getNodes().stream().filter(node -> node.getCategory().equals("mutation")).collect(Collectors.toList()));
+        objectSC.put("edges",null);
+
+        try {
+            FileWriter fw = new FileWriter(DownloadConstants.SAVE_PATH + "node/" + dto.getTargetId() + "_mutation.json");
+            PrintWriter out = new PrintWriter(fw);
+            out.write(objectSC.toString());
+            out.close();
+            fw.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+        JSONObject objectMu=new JSONObject();
+        objectMu.put("categories","sc");
+        objectMu.put("nodes",dto.getNodes().stream().filter(node -> node.getCategory().equals("sc")).collect(Collectors.toList()));
+        objectMu.put("edges",dto.getEdges());
+
+        try{
+            FileWriter fw1 = new FileWriter(DownloadConstants.SAVE_PATH + "node/" + dto.getTargetId() + "_sc.json");
+            PrintWriter out1 = new PrintWriter(fw1);
+            out1.write(objectMu.toString());
+            out1.close();
+            fw1.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    private TargetGraphDTO extractTargetGraph(ResponseEntity<JSONObject> dto){
+        JSONArray resultArray = dto.getBody().getJSONArray("_embedded");
+        if(resultArray.size() == 0) {
+            return null;
+        }else{
+            JSONObject result = resultArray.getJSONObject(0);
+            Gson gson = new Gson();
+            TargetGraphDTO targetGraphDTO = gson.fromJson(result.toString(), TargetGraphDTO.class);
+            targetGraphDTO.setId(result.getJSONObject("_id").getString("$oid"));
+            return targetGraphDTO;
+        }
+    }
+
+    private TargetGraphDTO createTargetGraph(HttpEntity<TargetGraphDTO> httpEntity, TargetGraphDTO targetGraphDTO){
+        RestTemplate rt = new RestTemplate();
+        String url = MongoAPIUtils.generateCommonUrl(mongoDBConfig.getDb(),
+                mongoDBConfig.getTargetGraphCollection());
+        System.out.println(url);
+        rt.exchange(url, HttpMethod.POST, httpEntity, String.class);
+        return targetGraphDTO;
+    }
+
+    private TargetGraphDTO updateTargetGraph(HttpEntity<TargetGraphDTO> httpEntity, TargetGraphDTO targetGraphDTO){
+        RestTemplate rt = new RestTemplate();
+        String url = MongoAPIUtils.generateUrlWithResourceId(mongoDBConfig.getDb(),
+                mongoDBConfig.getTargetGraphCollection(), targetGraphDTO.getId());
+        rt.exchange(url, HttpMethod.PUT, httpEntity, String.class);
+        return targetGraphDTO;
+    }
+
+}

+ 7 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/TargetServiceImpl.java

@@ -11,6 +11,7 @@ import cn.iselab.mooctest.site.models.fromKibug.Application;
 import cn.iselab.mooctest.site.models.fromKibug.IncrementId;
 import cn.iselab.mooctest.site.models.fromKibug.IncrementId;
 import cn.iselab.mooctest.site.service.BaseService;
 import cn.iselab.mooctest.site.service.BaseService;
 import cn.iselab.mooctest.site.service.TargetService;
 import cn.iselab.mooctest.site.service.TargetService;
+import cn.iselab.mooctest.site.service.fromDev.AnalysisService;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Page;
@@ -170,4 +171,10 @@ public class TargetServiceImpl extends BaseService implements TargetService {
     public void verifyApp(App app) {
     public void verifyApp(App app) {
         targetDao.save(app);
         targetDao.save(app);
     }
     }
+
+    @Override
+    public void rejectTarget(long targetId){
+        App app=appDao.findOne(targetId);
+        app.setStatus(-1);
+    }
 }
 }

+ 250 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/WechatController.java

@@ -1,9 +1,13 @@
 package cn.iselab.mooctest.site.web.ctrl;
 package cn.iselab.mooctest.site.web.ctrl;
 
 
 import cn.iselab.mooctest.site.common.constant.UrlConstants;
 import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.service.TargetGraphService;
+import cn.iselab.mooctest.site.web.data.forMongo.TargetGraphDTO;
+import cn.iselab.mooctest.site.web.data.forMongo.caseGraph.Category;
 import cn.iselab.mooctest.site.web.data.internal.*;
 import cn.iselab.mooctest.site.web.data.internal.*;
 import cn.iselab.mooctest.site.web.logic.ApiLogic;
 import cn.iselab.mooctest.site.web.logic.ApiLogic;
 import cn.iselab.mooctest.site.web.logic.WechatLogic;
 import cn.iselab.mooctest.site.web.logic.WechatLogic;
+import com.google.gson.Gson;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -11,6 +15,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
 
 
 /**
 /**
  * @author sean
  * @author sean
@@ -26,7 +32,8 @@ public class WechatController extends BaseController {
     @Autowired
     @Autowired
     private WechatLogic wechatLogic;
     private WechatLogic wechatLogic;
 
 
-
+    @Autowired
+    private TargetGraphService targetGraphService;
     /**
     /**
      *
      *
      * GET methods
      * GET methods
@@ -111,4 +118,246 @@ public class WechatController extends BaseController {
     public String joinGroup(HttpServletRequest request, @RequestBody JoinGroupWechatVO body) {
     public String joinGroup(HttpServletRequest request, @RequestBody JoinGroupWechatVO body) {
         return wechatLogic.joinGroup(request, body);
         return wechatLogic.joinGroup(request, body);
     }
     }
+
+    @RequestMapping(value = UrlConstants.API_WECHAT + "test", method = RequestMethod.GET)
+    public String Test(){
+        String str="{\n" +
+                "    \"categories\": [\n" +
+                "        {\n" +
+                "            \"name\": \"mutation\"\n" +
+                "        }\n" +
+                "    ],\n" +
+                "    \"nodes\": [\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_1\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_2\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_3\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_4\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_5\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_6\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_7\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_8\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_9\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_10\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_11\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_12\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/29\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_14\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/34\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_15\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/34\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_17\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/35\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_18\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/35\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_20\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/36\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_21\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/36\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_23\",\n" +
+                "            \"description\": \"replaced return of integer sized value with (x == 0 ? 1 : 0) \",\n" +
+                "            \"location\": \"Triangle.java/41\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_25\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/52\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_27\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/54\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_28\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/54\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_30\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/59\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_31\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/59\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_32\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/59\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_34\",\n" +
+                "            \"description\": \"mutated return of Object value for net/mooctest/mutation/analysis/Triangle::getType to ( if (x != null) null else throw new RuntimeException ) \",\n" +
+                "            \"location\": \"Triangle.java/70\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_36\",\n" +
+                "            \"description\": \"changed conditional boundary \",\n" +
+                "            \"location\": \"Triangle.java/78\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_37\",\n" +
+                "            \"description\": \"Replaced long subtraction with addition \",\n" +
+                "            \"location\": \"Triangle.java/78\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_38\",\n" +
+                "            \"description\": \"Replaced long subtraction with addition \",\n" +
+                "            \"location\": \"Triangle.java/78\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_39\",\n" +
+                "            \"description\": \"negated conditional \",\n" +
+                "            \"location\": \"Triangle.java/78\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_40\",\n" +
+                "            \"description\": \"replaced return of long value with value + 1 for net/mooctest/mutation/analysis/Triangle::diffOfBorders \",\n" +
+                "            \"location\": \"Triangle.java/78\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        },\n" +
+                "        {\n" +
+                "            \"name\": \"Triangle.java_42\",\n" +
+                "            \"description\": \"mutated return of Object value for net/mooctest/mutation/analysis/Triangle::getBorders to ( if (x != null) null else throw new RuntimeException ) \",\n" +
+                "            \"location\": \"Triangle.java/89\",\n" +
+                "            \"category\": \"mutation\",\n" +
+                "            \"img\": null\n" +
+                "        }\n" +
+                "    ],\n" +
+                "    \"edges\": null\n" +
+                "}";
+        TargetGraphDTO dto=new Gson().fromJson(str,TargetGraphDTO.class);
+        dto.setTargetId(419L);
+        targetGraphService.saveTargetGraphJson(dto);
+        return "ok";
+    }
 }
 }

+ 33 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/forMongo/TargetGraphDTO.java

@@ -0,0 +1,33 @@
+package cn.iselab.mooctest.site.web.data.forMongo;
+
+import cn.iselab.mooctest.site.web.data.forMongo.caseGraph.Category;
+import cn.iselab.mooctest.site.web.data.forMongo.caseGraph.Edge;
+import cn.iselab.mooctest.site.web.data.forMongo.caseGraph.Node;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author ROKG
+ * @Description
+ * @Date: Created in 下午5:30 2018/1/16
+ * @Modified By:
+ */
+@Data
+public class TargetGraphDTO {
+    String id;
+    Long targetId;
+    List<Category> categories;
+    List<Node> nodes;
+    List<Edge> edges;
+
+    public boolean checkNodeNameUnique(){
+        long count = nodes.stream().map(Node::getName).count();
+        long distinctCount = nodes.stream().map(Node::getName).distinct().count();
+        boolean unique = count == distinctCount;
+        if(!unique){
+            throw new IllegalArgumentException("node name must be unique!");
+        }
+        return unique;
+    }
+}

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/TargetLogic.java

@@ -37,4 +37,6 @@ public interface TargetLogic {
     TargetVO getTargetById(Long targetId);
     TargetVO getTargetById(Long targetId);
 
 
     NodeUrlVO getTargetNode(Long targetId);
     NodeUrlVO getTargetNode(Long targetId);
+
+    void getTargetGraph(long targetId,long targetType,String url);
 }
 }

+ 7 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/APFDLogic.java

@@ -3,6 +3,9 @@ package cn.iselab.mooctest.site.web.logic.fromDev;
 import cn.iselab.mooctest.site.models.Weight;
 import cn.iselab.mooctest.site.models.Weight;
 import cn.iselab.mooctest.site.rpc.dev.data.ApbcDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.ApbcDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
+import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
+
+import java.util.List;
 
 
 /**
 /**
  * @author sean
  * @author sean
@@ -18,4 +21,8 @@ public interface APFDLogic {
     String getMutationAnalyseofCaseInExam(Long examId, Long caseId, Long participantId);
     String getMutationAnalyseofCaseInExam(Long examId, Long caseId, Long participantId);
 
 
     MutationDTO getMutationAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long workerId) throws Exception;
     MutationDTO getMutationAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long workerId) throws Exception;
+
+    String getMutationNodeAnalyseofCaseInExam(Long examId, Long caseId, Long participantId);
+
+    List<CaughtNodeDTO> getMutationNodeAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long workerId);
 }
 }

+ 63 - 5
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/impl/APFDLogicImpl.java

@@ -5,7 +5,9 @@ import cn.iselab.mooctest.site.models.Exam2Case;
 import cn.iselab.mooctest.site.models.Grade;
 import cn.iselab.mooctest.site.models.Grade;
 import cn.iselab.mooctest.site.models.Weight;
 import cn.iselab.mooctest.site.models.Weight;
 import cn.iselab.mooctest.site.rpc.dev.data.ApbcDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.ApbcDTO;
+import cn.iselab.mooctest.site.rpc.dev.data.CaughtNodeDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
+import cn.iselab.mooctest.site.rpc.dev.data.NodeResultDTO;
 import cn.iselab.mooctest.site.service.*;
 import cn.iselab.mooctest.site.service.*;
 import cn.iselab.mooctest.site.service.common.MongoAPIService;
 import cn.iselab.mooctest.site.service.common.MongoAPIService;
 import cn.iselab.mooctest.site.service.fromDev.AnalysisService;
 import cn.iselab.mooctest.site.service.fromDev.AnalysisService;
@@ -18,6 +20,7 @@ import cn.iselab.mooctest.site.web.logic.CalculateSocreLogic;
 import cn.iselab.mooctest.site.web.logic.fromDev.APFDLogic;
 import cn.iselab.mooctest.site.web.logic.fromDev.APFDLogic;
 import cn.iselab.mooctest.site.web.data.forMongo.MutationForMongoDTO;
 import cn.iselab.mooctest.site.web.data.forMongo.MutationForMongoDTO;
 import cn.iselab.mooctest.site.web.logic.impl.CalculateScoreLogicImpl;
 import cn.iselab.mooctest.site.web.logic.impl.CalculateScoreLogicImpl;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -125,6 +128,32 @@ public class APFDLogicImpl extends BaseLogic implements APFDLogic{
     }
     }
 
 
     @Override
     @Override
+    public String getMutationNodeAnalyseofCaseInExam(Long examId, Long caseId, Long participantId){
+        if (weightService.getWeightByTidAndCid(examId, caseId) == null) {
+            throw new HttpBadRequestException("unmatched examId and caseId");
+        }
+        Weight weight = weightService.getWeightByTidAndCid(examId, caseId);
+        if (weight.getMutation() == 0) {
+            throw new HttpBadRequestException(caseId + "'s 变异分析 is 0");
+        }
+        if(participantId==null) {
+            List<AssignedTask> assignedTasks = assignedTaskService.getSubmittedRecordsByExamId(examId);
+            List<Long> submittedWorkerIds = assignedTasks.stream().map(assignedTask -> assignedTask.getParticipantId()).collect(Collectors.toList());
+            LOG.info("---------------------------------start mutation analysis--------------------------------");
+            List<List<cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO>> mutationDTOS =submittedWorkerIds.stream().map( submittedWorkerId ->
+                    getMutationNodeAnalyseByExamIdAndParticipantId(examId,caseId,submittedWorkerId)).filter(dTO-> dTO!=null).collect(Collectors.toList());
+            LOG.info("---------------------------------end mutation analysis--------------------------------");
+            if (mutationDTOS.size() != 0 && !mutationDTOS.isEmpty()) {
+                return StResponse.success(mutationDTOS);
+            } else {
+                throw new HttpBadRequestException("获取变异分析失败");
+            }
+        }else {
+            return StResponse.success(getMutationNodeAnalyseByExamIdAndParticipantId(examId, caseId, participantId));
+        }
+    }
+
+    @Override
     public MutationDTO getMutationAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long participantId){
     public MutationDTO getMutationAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long participantId){
         MutationDTO mutationDTO;
         MutationDTO mutationDTO;
         try {
         try {
@@ -136,9 +165,7 @@ public class APFDLogicImpl extends BaseLogic implements APFDLogic{
         if (mutationDTO == null) {
         if (mutationDTO == null) {
             throw new HttpBadRequestException("Fail to get 变异分析 of No." + caseId);
             throw new HttpBadRequestException("Fail to get 变异分析 of No." + caseId);
         } else {
         } else {
-            double mutationScore=0;
-            if(mutationDTO.getTotal()!=0)
-                 mutationScore= (double) mutationDTO.getKilled() / mutationDTO.getTotal() * 100;
+            double mutationScore= mutationDTO.getTotal()==0?0:(double) mutationDTO.getKilled() / mutationDTO.getTotal() * 100;
             try {
             try {
                 List<Grade> grades = analysisService.saveMutationScore(participantId, examId, caseId, mutationScore);
                 List<Grade> grades = analysisService.saveMutationScore(participantId, examId, caseId, mutationScore);
                 if (grades != null && !grades.isEmpty()) {
                 if (grades != null && !grades.isEmpty()) {
@@ -150,12 +177,43 @@ public class APFDLogicImpl extends BaseLogic implements APFDLogic{
                     MutationForMongoDTO mutationForMongoDTO = list.get(0);
                     MutationForMongoDTO mutationForMongoDTO = list.get(0);
                     mutationForMongoDTO.setMutationDTO(mutationDTO);
                     mutationForMongoDTO.setMutationDTO(mutationDTO);
                     mongoAPIService.updateMutationToMongo(mutationForMongoDTO);
                     mongoAPIService.updateMutationToMongo(mutationForMongoDTO);
-                }else
-                    mongoAPIService.saveMutationToMongo(participantId,examId,caseId,mutationDTO);
+                }else {
+                    mongoAPIService.saveMutationToMongo(participantId, examId, caseId, mutationDTO);
+                }
             }catch (IOException e){
             }catch (IOException e){
                 throw new IllegalOperationException("mongo io exception");
                 throw new IllegalOperationException("mongo io exception");
             }
             }
             return mutationDTO;
             return mutationDTO;
         }
         }
     }
     }
+
+    @Override
+    public List<cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO> getMutationNodeAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long workerId){
+        List<CaughtNodeDTO> caughtNodeDTOS;
+        try {
+            caughtNodeDTOS = analysisService.mutationCaughtNodeAnalyze(examId,workerId,caseId);
+        }catch (Exception e){
+            e.printStackTrace();
+            return null;
+        }
+
+        if (caughtNodeDTOS == null) {
+            throw new HttpBadRequestException("Fail to get 变异分析 of No." + caseId);
+        } else {
+            List<cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO> dtos=caughtNodeDTOS.stream().map(dto -> {
+                cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO node=new cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO();
+                BeanUtils.copyProperties(dto,node);
+                return node;
+            }).collect(Collectors.toList());
+            long catchNum=dtos.stream().filter(caughtNodeDTO -> caughtNodeDTO.getIfCatch()==true).count();
+            double mutationScore=dtos.size()==0?0:(double) catchNum/dtos.size();
+            List<Grade> grades = analysisService.saveMutationScore(workerId, examId, caseId, mutationScore);
+            if (grades != null && !grades.isEmpty()) {
+                calculateScoreService.calculatePersonalDevScore(examId, caseId, workerId);
+                calculateSocreLogic.calculateExamScoreAuto(examId,workerId);
+            }
+            calculateSocreLogic.catchNode(examId,caseId,workerId,String.valueOf(System.currentTimeMillis()),dtos);
+            return dtos;
+        }
+    }
 }
 }

+ 1 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/OSSLogicImpl.java

@@ -119,7 +119,7 @@ public class OSSLogicImpl implements OSSLogic {
 
 
     @Override
     @Override
     public String getTargetKey(String appName) {
     public String getTargetKey(String appName) {
-        return AliyunOSSConstants.PATH_TARGET + System.currentTimeMillis() + "_" + appName;
+        return AliyunOSSConstants.PATH_TARGET + FilenameUtils.removeExtension(appName) + "_" + System.currentTimeMillis()+"."+FilenameUtils.getExtension(appName);
     }
     }
 
 
     @Override
     @Override

+ 50 - 2
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/TargetLogicImpl.java

@@ -1,27 +1,35 @@
 package cn.iselab.mooctest.site.web.logic.impl;
 package cn.iselab.mooctest.site.web.logic.impl;
 
 
 import cn.iselab.mooctest.site.common.constant.TargetTypeConstants;
 import cn.iselab.mooctest.site.common.constant.TargetTypeConstants;
+import cn.iselab.mooctest.site.common.event.EventUtil;
+import cn.iselab.mooctest.site.common.event.GetTargetGraphEvent;
 import cn.iselab.mooctest.site.common.web.ErrorResult;
 import cn.iselab.mooctest.site.common.web.ErrorResult;
 import cn.iselab.mooctest.site.common.web.ResponseMessage;
 import cn.iselab.mooctest.site.common.web.ResponseMessage;
 import cn.iselab.mooctest.site.common.web.StatusCode;
 import cn.iselab.mooctest.site.common.web.StatusCode;
 import cn.iselab.mooctest.site.common.web.SuccessResult;
 import cn.iselab.mooctest.site.common.web.SuccessResult;
 import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.models.fromKibug.Application;
 import cn.iselab.mooctest.site.models.fromKibug.Application;
+import cn.iselab.mooctest.site.rpc.dev.data.NodeResultDTO;
 import cn.iselab.mooctest.site.service.AppService;
 import cn.iselab.mooctest.site.service.AppService;
+import cn.iselab.mooctest.site.service.TargetGraphService;
 import cn.iselab.mooctest.site.service.TargetService;
 import cn.iselab.mooctest.site.service.TargetService;
 import cn.iselab.mooctest.site.service.common.NodeUrlService;
 import cn.iselab.mooctest.site.service.common.NodeUrlService;
+import cn.iselab.mooctest.site.service.fromDev.AnalysisService;
 import cn.iselab.mooctest.site.service.fromKibug.ApplicationService;
 import cn.iselab.mooctest.site.service.fromKibug.ApplicationService;
 import cn.iselab.mooctest.site.service.instancePermission.AppPermissionService;
 import cn.iselab.mooctest.site.service.instancePermission.AppPermissionService;
 import cn.iselab.mooctest.site.web.data.*;
 import cn.iselab.mooctest.site.web.data.*;
+import cn.iselab.mooctest.site.web.data.forMongo.TargetGraphDTO;
 import cn.iselab.mooctest.site.web.data.wrapper.TargetDevVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.TargetDevVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.TargetKibugVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.TargetKibugVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.TargetVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.TargetVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.TargetWebVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.TargetWebVOWrapper;
 import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
 import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
 import cn.iselab.mooctest.site.web.exception.HttpNotFoundException;
 import cn.iselab.mooctest.site.web.exception.HttpNotFoundException;
+import cn.iselab.mooctest.site.web.logic.BaseLogic;
 import cn.iselab.mooctest.site.web.logic.TargetLogic;
 import cn.iselab.mooctest.site.web.logic.TargetLogic;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authz.UnauthorizedException;
 import org.apache.shiro.authz.UnauthorizedException;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Page;
@@ -35,7 +43,7 @@ import java.util.Map;
  * Created by ROGK on 2017/6/18.
  * Created by ROGK on 2017/6/18.
  */
  */
 @Service
 @Service
-public class TargetLogicImpl implements TargetLogic {
+public class TargetLogicImpl extends BaseLogic implements TargetLogic {
 
 
     @Autowired
     @Autowired
     private AppService appService;
     private AppService appService;
@@ -64,6 +72,15 @@ public class TargetLogicImpl implements TargetLogic {
     @Autowired
     @Autowired
     private NodeUrlService nodeUrlService;
     private NodeUrlService nodeUrlService;
 
 
+    @Autowired
+    private AnalysisService analysisService;
+
+    @Autowired
+    private TargetGraphService targetGraphService;
+
+    @Autowired
+    EventUtil eventUtil;
+
     @Override
     @Override
     public List<TargetVO> getManagerTargets(long managerId) throws Exception {
     public List<TargetVO> getManagerTargets(long managerId) throws Exception {
 
 
@@ -108,9 +125,10 @@ public class TargetLogicImpl implements TargetLogic {
         App app = targetKibugVOWrapper.wrapApp(vo);
         App app = targetKibugVOWrapper.wrapApp(vo);
         Application application = targetKibugVOWrapper.unwrap(vo);
         Application application = targetKibugVOWrapper.unwrap(vo);
         app = appService.uploadCase(app);
         app = appService.uploadCase(app);
-//        setPemission(app);
+        setPemission(app);
         application.setUploadedCaseId(app.getId());
         application.setUploadedCaseId(app.getId());
         applicationService.createApp(application);
         applicationService.createApp(application);
+        setListener(app.getId(),app.getTargetType(),app.getUrl());
         return app.getId();
         return app.getId();
     }
     }
 
 
@@ -166,6 +184,7 @@ public class TargetLogicImpl implements TargetLogic {
         setPemission(app);
         setPemission(app);
         devTarget.setUploadedCaseId(app.getId());
         devTarget.setUploadedCaseId(app.getId());
         targetService.createTargetDev(devTarget);
         targetService.createTargetDev(devTarget);
+        setListener(app.getId(),app.getTargetType(),app.getUrl());
         return app.getId();
         return app.getId();
     }
     }
 
 
@@ -177,6 +196,7 @@ public class TargetLogicImpl implements TargetLogic {
         setPemission(app);
         setPemission(app);
         webTarget.setSuperId(app.getId());
         webTarget.setSuperId(app.getId());
         targetService.createTargetWeb(webTarget);
         targetService.createTargetWeb(webTarget);
+        setListener(app.getId(),app.getTargetType(),app.getUrl());
         return app.getId();
         return app.getId();
     }
     }
 
 
@@ -229,4 +249,32 @@ public class TargetLogicImpl implements TargetLogic {
         return vo;
         return vo;
     }
     }
 
 
+    @Override
+    public void getTargetGraph(long targetId,long targetType,String url){
+        TargetGraphDTO targetGraphDTO = new TargetGraphDTO();
+        targetGraphDTO.setTargetId(targetId);
+        if(targetType == TargetTypeConstants.DEV) {
+            try {
+                LOG.info("---------------------------------start mutation analysis--------------------------------");
+                NodeResultDTO nodeResultDTO = analysisService.mutationNodeAnalyze(url);
+                LOG.info("---------------------------------end mutation analysis--------------------------------");
+                if(nodeResultDTO!=null) {
+                    BeanUtils.copyProperties(nodeResultDTO, targetGraphDTO);
+                }else {
+                    targetService.rejectTarget(targetId);
+                }
+            }catch (Exception e){
+                e.printStackTrace();
+                targetService.rejectTarget(targetId);
+            }
+            targetGraphService.saveTargetGraphJson(targetGraphDTO);
+        }
+        targetGraphService.saveTargetGraph(targetGraphDTO);
+    }
+
+    private void setListener(long targetId,long targetType,String url){
+        GetTargetGraphEvent event=new GetTargetGraphEvent(targetId,url,targetType);
+        eventUtil.post(event);
+    }
+
 }
 }

+ 4 - 0
mooctest-site-server/src/main/resources/application.yaml

@@ -94,6 +94,7 @@ mongodb:
       competeAnalysisCollection: competeAnalysisResult
       competeAnalysisCollection: competeAnalysisResult
       difficultAnalysisCollection: difficultAnalysisResult
       difficultAnalysisCollection: difficultAnalysisResult
       timeAnalysisCollection: timeAnalysisResult
       timeAnalysisCollection: timeAnalysisResult
+      targetGraphCollection: targetGraph
       base64Auth: Basic YWRtaW46Y2hhbmdlaXQ=
       base64Auth: Basic YWRtaW46Y2hhbmdlaXQ=
 
 
 
 
@@ -161,6 +162,7 @@ mongodb:
       competeAnalysisCollection: competeAnalysisResult
       competeAnalysisCollection: competeAnalysisResult
       difficultAnalysisCollection: difficultAnalysisResult
       difficultAnalysisCollection: difficultAnalysisResult
       timeAnalysisCollection: timeAnalysisResult
       timeAnalysisCollection: timeAnalysisResult
+      targetGraphCollection: targetGraph
       base64Auth: Basic YWRtaW46Y2hhbmdlaXQ=
       base64Auth: Basic YWRtaW46Y2hhbmdlaXQ=
 server:
 server:
     port: 9001
     port: 9001
@@ -227,6 +229,7 @@ mongodb:
       competeAnalysisCollection: competeAnalysisResult
       competeAnalysisCollection: competeAnalysisResult
       difficultAnalysisCollection: difficultAnalysisResult
       difficultAnalysisCollection: difficultAnalysisResult
       timeAnalysisCollection: timeAnalysisResult
       timeAnalysisCollection: timeAnalysisResult
+      targetGraphCollection: targetGraph
       base64Auth: Basic YWRtaW46Y2hhbmdlaXQ=
       base64Auth: Basic YWRtaW46Y2hhbmdlaXQ=
 
 
 server:
 server:
@@ -287,6 +290,7 @@ mongodb:
       competeAnalysisCollection: competeAnalysisResult
       competeAnalysisCollection: competeAnalysisResult
       difficultAnalysisCollection: difficultAnalysisResult
       difficultAnalysisCollection: difficultAnalysisResult
       timeAnalysisCollection: timeAnalysisResult
       timeAnalysisCollection: timeAnalysisResult
+      targetGraphCollection: targetGraph
       base64Auth:
       base64Auth:
 
 
 server:
 server: