sky пре 5 година
родитељ
комит
9e939362b9

+ 38 - 0
seec-data-server/src/main/java/cn/seecoder/data/server/dto/sonarqube/ComponentTreeDto.java

@@ -0,0 +1,38 @@
+package cn.seecoder.data.server.dto.sonarqube;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ComponentTreeDto {
+    private BaseComponent baseComponent;
+    private List<Component> components;
+
+    @Data
+    public static class BaseComponent {
+        private String name;
+        private List<Measure> measures;
+
+    }
+
+    @Data
+    public static class Component {
+        private String key;
+        private String qualifier;
+        private String path;
+        private List<Measure> measures;
+    }
+
+    @Data
+    public static class Measure {
+        private String metric;
+        private String value;
+
+        public String getValue() {
+            if(metric.equals("duplicated_lines_density")) return value;
+            int interval = (int)Double.parseDouble(value) - 1;
+            return String.valueOf((char) ('A' + interval));
+        }
+    }
+}

+ 3 - 0
seec-data-server/src/main/java/cn/seecoder/data/server/repository/SonarCoderRepository.java

@@ -4,6 +4,9 @@ import cn.seecoder.data.server.domain.sonar.SonarCoderDao;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+
 @Repository
 public interface SonarCoderRepository extends JpaRepository<SonarCoderDao,String> {
+    List<SonarCoderDao> findAllByUserId(Integer userId);
 }

+ 84 - 0
seec-data-server/src/main/java/cn/seecoder/data/server/service/Impl/SonarqubeServiceImpl.java

@@ -0,0 +1,84 @@
+package cn.seecoder.data.server.service.Impl;
+
+import cn.seecoder.data.server.domain.sonar.SonarCoderDao;
+import cn.seecoder.data.server.dto.sonarqube.ComponentTreeDto;
+import cn.seecoder.data.server.repository.SonarCoderRepository;
+import cn.seecoder.data.server.service.SonarqubeService;
+import cn.seecoder.data.server.utils.enums.ErrorCodeEnum;
+import cn.seecoder.data.server.utils.exception.GlobalException;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+@Service
+public class SonarqubeServiceImpl implements SonarqubeService {
+
+    @Autowired
+    private SonarCoderRepository sonarCoderRepository;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Value("${sys.sonarqube.url}")
+    private String sonarBaseUrl;
+
+    @Override
+    public double getSonarScoreOfUser(int userId) { // 所有项目取平均分 , 100.0 满分
+        List<ComponentTreeDto> componentTreeDtos = getSonarDataOfUser(userId);
+        double sum = componentTreeDtos.stream().mapToDouble(componentTreeDto -> handleMeasures(componentTreeDto.getBaseComponent().getMeasures())).sum();
+        return sum / componentTreeDtos.size();
+    }
+
+    private double handleMeasures(List<ComponentTreeDto.Measure> measures) { // 单个项目得分计算
+        AtomicReference<Double> sum = new AtomicReference<>(0.0);
+        measures.forEach(measure -> {
+            if(measure.getMetric().equals("duplicated_lines_density")) sum.updateAndGet(v -> (double) (v + 100.0 - Double.parseDouble(measure.getValue())));
+            else sum.updateAndGet(v -> (double) (v + (5 - (measure.getValue().charAt(0) - 'A')) * 20.0));
+        });
+        return sum.get() / measures.size();
+    }
+
+    private List<ComponentTreeDto> getSonarDataOfUser(int userId) { // note: 以后devcloud接入sonar之后,此处源码需要修改
+        // 1. fetch sonarName by userId
+        List<SonarCoderDao> sonarCoderDaos = sonarCoderRepository.findAllByUserId(userId);
+        // 2. fetch sonarComponentTreeDto by sonarName
+        List<ComponentTreeDto> componentTreeDtos = new LinkedList<>();
+        sonarCoderDaos.forEach(sonarCoderDao -> {
+            try {
+                ComponentTreeDto componentTreeDto = fetchSonarDataBySonarName(sonarCoderDao.getSonarName());
+                componentTreeDtos.add(componentTreeDto);
+            } catch (Exception e){
+                LoggerFactory.getLogger(getClass()).error("sonar: Cannot get data by sonarname '" + sonarCoderDao.getSonarName() + "' !" );
+            }
+        });
+        return componentTreeDtos;
+    }
+
+    private ComponentTreeDto fetchSonarDataBySonarName(String sonarName) {
+        String sonarUrl = sonarBaseUrl + "/api/measures/component_tree?" +
+                "qualifiers=TRK" +
+                "&p=1&ps=500" +
+                "&metricKeys=reliability_rating,security_rating,sqale_rating,duplicated_lines_density" +
+                "&component=" +
+                sonarName;
+        ParameterizedTypeReference<ComponentTreeDto> responseType = new ParameterizedTypeReference<ComponentTreeDto>() {};
+        try {
+            ResponseEntity<ComponentTreeDto> r = restTemplate.exchange(sonarUrl,HttpMethod.GET,null,responseType,new HashMap<>());
+            ComponentTreeDto body = r.getBody();
+            return body;
+        }catch (Throwable e) {
+            throw new GlobalException(ErrorCodeEnum.SERVICE_ERROR_C0007);
+        }
+    }
+
+}

+ 5 - 0
seec-data-server/src/main/java/cn/seecoder/data/server/service/SonarqubeService.java

@@ -0,0 +1,5 @@
+package cn.seecoder.data.server.service;
+
+public interface SonarqubeService {
+    double getSonarScoreOfUser(int userId);
+}

+ 3 - 1
seec-data-server/src/main/java/cn/seecoder/data/server/utils/enums/ErrorCodeEnum.java

@@ -20,7 +20,9 @@ public enum ErrorCodeEnum {
     SERVICE_ERROR_C0003("C0003", "数据抽取源无数据"),
     SERVICE_ERROR_C0004("C0004", "请求参数不合法"),
     SERVICE_ERROR_C0005("C0005", "请求参数不匹配"),
-    SERVICE_ERROR_C0006("C0006", "请求方法不支持");
+    SERVICE_ERROR_C0006("C0006", "请求方法不支持"),
+    SERVICE_ERROR_C0007("C0007", "远程api调用错误");
+
 
 
 

+ 8 - 4
seec-data-server/src/main/resources/application.yml

@@ -15,8 +15,8 @@ logging:
     path: logs
 
 jwt:
-  secret: 'SEEC-1919810-OIDC-114514'
-  sys-secret: '114514-OIDC-1919810-SEEC-ANALYSIS'
+  secret: SEEC-1919810-OIDC-114514
+  sys-secret: 114514-OIDC-1919810-SEEC-ANALYSIS
 
 sys:
   coder:
@@ -27,5 +27,9 @@ sys:
   devcloud:
     url: 'devcloud'
   gitlab:
-    url: 'gitlab'
-    token: 'token'
+    url: http://gitlab.seecoder.cn/
+    token: 'token'
+  sonarqube:
+    url: http://139.196.193.252:9000/
+    login: admin
+    password: NJU67sonarqube