ソースを参照

client-server初始化

blumonilr 5 年 前
コミット
75c2ed90d1
45 ファイル変更1071 行追加135 行削除
  1. 36 74
      pom.xml
  2. 42 0
      seecoder-gitlab-client/pom.xml
  3. 47 0
      seecoder-gitlab-client/src/main/java/com.nju.edu.gitlab/SeecoderGitlabApi.java
  4. 505 0
      seecoder-gitlab-client/src/main/java/com.nju.edu.gitlab/SeecoderGitlabClient.java
  5. 34 0
      seecoder-gitlab-client/src/main/java/com.nju.edu.gitlab/SeecoderGitlabException.java
  6. 18 0
      seecoder-gitlab-client/src/test/java/GitlabClientTest.java
  7. 26 0
      seecoder-gitlab-common/pom.xml
  8. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/ChangePasswordDTO.java
  9. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/GitlabUserDTO.java
  10. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/GroupForkDTO.java
  11. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/ProjectFileDTO.java
  12. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/ProjectRawFileDTO.java
  13. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/UserForkDTO.java
  14. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/WebHookDTO.java
  15. 25 0
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/commit/CommitActionForm.java
  16. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/commit/CommitDTO.java
  17. 11 0
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/member/AccessLevelForm.java
  18. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/member/GroupMemberDTO.java
  19. 3 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/project/ProjectDTO.java
  20. 10 0
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/project/VisibilityForm.java
  21. 16 0
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/BranchVO.java
  22. 19 0
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/DiffVO.java
  23. 1 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/GitlabGroup.java
  24. 1 1
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/GitlabUser.java
  25. 19 0
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/commit/CommitStatsVO.java
  26. 30 0
      seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/commit/CommitVO.java
  27. 93 0
      seecoder-gitlab-server/pom.xml
  28. 0 0
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/GitlabApplication.java
  29. 2 3
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/controller/GitlabGroupController.java
  30. 6 4
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/controller/GitlabProjectController.java
  31. 2 3
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/controller/GitlabUserController.java
  32. 2 2
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/api/GroupService.java
  33. 10 8
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/api/ProjectService.java
  34. 3 4
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/api/UserService.java
  35. 2 3
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/impl/GroupServiceImpl.java
  36. 75 15
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/impl/ProjectServiceImpl.java
  37. 5 6
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/impl/UserServiceImpl.java
  38. 0 0
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/util/ApplicationProperties.java
  39. 0 0
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/util/Tools.java
  40. 1 1
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/handler/ApiExceptionHandler.java
  41. 0 0
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/response/EmptyResponse.java
  42. 0 0
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/response/ErrorResponse.java
  43. 0 0
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/response/ResourceResponse.java
  44. 0 0
      seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/response/Response.java
  45. 0 0
      seecoder-gitlab-server/src/main/resources/application.yml

+ 36 - 74
pom.xml

@@ -8,88 +8,50 @@
         <version>2.3.4.RELEASE</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
+
     <groupId>com.nju.edu</groupId>
-    <artifactId>gitlab</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-    <name>gitlab</name>
+    <artifactId>seecoder-gitlab</artifactId>
+    <version>0.1.0</version>
+    <packaging>pom</packaging>
     <description>Gitlab API project</description>
+    <modules>
+        <module>seecoder-gitlab-common</module>
+        <module>seecoder-gitlab-server</module>
+        <module>seecoder-gitlab-client</module>
+    </modules>
 
     <properties>
         <java.version>1.8</java.version>
+        <seecoder-gitlab-version>0.1.0</seecoder-gitlab-version>
     </properties>
 
-    <dependencies>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-data-jpa</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-mail</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-security</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-thymeleaf</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.thymeleaf.extras</groupId>
-            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
-        </dependency>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.gitlab4j</groupId>
+                <artifactId>gitlab4j-api</artifactId>
+                <version>4.15.7</version>
+            </dependency>
+            <dependency>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-java</artifactId>
+                <version>8.0.20</version>
+            </dependency>
+
+            <dependency>
+                <groupId>cn.seecoder</groupId>
+                <artifactId>seecoder-gitlab-common</artifactId>
+                <version>${seecoder-gitlab-version}</version>
+            </dependency>
+        </dependencies>
 
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-devtools</artifactId>
-            <scope>runtime</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.junit.vintage</groupId>
-                    <artifactId>junit-vintage-engine</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.security</groupId>
-            <artifactId>spring-security-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.gitlab4j</groupId>
-            <artifactId>gitlab4j-api</artifactId>
-            <version>4.15.7</version>
-        </dependency>
-        <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <version>8.0.20</version>
-        </dependency>
-    </dependencies>
+    </dependencyManagement>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.springframework.boot</groupId>
-                <artifactId>spring-boot-maven-plugin</artifactId>
-            </plugin>
-        </plugins>
-    </build>
+    <distributionManagement>
+        <repository>
+            <id>nexus</id>
+            <url>http://nexus.seecoder.cn/repository/maven-releases</url>
+        </repository>
+    </distributionManagement>
 
 </project>

+ 42 - 0
seecoder-gitlab-client/pom.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>seecoder-gitlab</artifactId>
+        <groupId>com.nju.edu</groupId>
+        <version>0.1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>seecoder-gitlab-client</artifactId>
+
+    <properties>
+        <seecoder-gitlab-version>0.1.0</seecoder-gitlab-version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.nju.edu</groupId>
+            <artifactId>seecoder-gitlab-common</artifactId>
+            <version>${seecoder-gitlab-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.gitlab4j</groupId>
+            <artifactId>gitlab4j-api</artifactId>
+            <version>4.8.7</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>5.6.2</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 47 - 0
seecoder-gitlab-client/src/main/java/com.nju.edu.gitlab/SeecoderGitlabApi.java

@@ -0,0 +1,47 @@
+package com.nju.edu.gitlab;
+
+import com.nju.edu.gitlab.dto.*;
+import com.nju.edu.gitlab.dto.commit.CommitActionForm;
+import com.nju.edu.gitlab.dto.member.AccessLevelForm;
+import com.nju.edu.gitlab.dto.project.VisibilityForm;
+import com.nju.edu.gitlab.vo.*;
+import com.nju.edu.gitlab.vo.commit.CommitVO;
+
+
+import java.util.List;
+import java.util.Set;
+
+public interface SeecoderGitlabApi{
+
+    public GitlabUser createGitlabUser(String username,String password,String email) throws SeecoderGitlabException;
+
+    public boolean changePassword(int userId,String password) throws SeecoderGitlabException;
+
+    public boolean deleteUser(int userId) throws SeecoderGitlabException;
+
+    public GitlabGroup createGroup(String groupName) throws SeecoderGitlabException;
+
+    public boolean addMember(int groupId, int userId, AccessLevelForm accessLevel) throws SeecoderGitlabException;
+
+    public Integer createProject(String projectName,VisibilityForm visibility) throws SeecoderGitlabException;
+
+    public Integer forkProject(int projectId, int userId) throws SeecoderGitlabException;
+
+    public Integer forkGroupProject(int projectId,int groupId) throws SeecoderGitlabException;
+
+    public Set<DiffVO> compare(int projectId, String fromBash, String toBash) throws SeecoderGitlabException;
+
+    public boolean addWebHook(int projectId,String url,boolean doPushEvents,boolean doIssueEvents,boolean doMergeRequestsEvents) throws SeecoderGitlabException;
+
+    public boolean archiveProject(int projectId) throws SeecoderGitlabException;
+
+    public String getProjectFile(int projectId, String branch,String path) throws SeecoderGitlabException;
+
+    public String getProjectRawFile(int projectId,String commitOrBranchName,String path) throws SeecoderGitlabException;
+
+    public CommitVO createCommit(int projectId, String branch,String commitMessage,String email,String username,List<CommitActionForm> actions) throws SeecoderGitlabException;
+
+    public List<CommitVO> getAllCommitMessage(int projectId, String commitHash) throws SeecoderGitlabException;
+
+    public List<BranchVO> getProjectBranches(int projectId) throws SeecoderGitlabException;
+}

+ 505 - 0
seecoder-gitlab-client/src/main/java/com.nju.edu.gitlab/SeecoderGitlabClient.java

@@ -0,0 +1,505 @@
+package com.nju.edu.gitlab;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nju.edu.gitlab.dto.*;
+import com.nju.edu.gitlab.dto.commit.CommitActionForm;
+import com.nju.edu.gitlab.dto.commit.CommitDTO;
+import com.nju.edu.gitlab.dto.member.AccessLevelForm;
+import com.nju.edu.gitlab.dto.member.GroupMemberDTO;
+import com.nju.edu.gitlab.dto.project.ProjectDTO;
+import com.nju.edu.gitlab.dto.project.VisibilityForm;
+import com.nju.edu.gitlab.vo.BranchVO;
+import com.nju.edu.gitlab.vo.DiffVO;
+import com.nju.edu.gitlab.vo.GitlabGroup;
+import com.nju.edu.gitlab.vo.GitlabUser;
+import com.nju.edu.gitlab.vo.commit.CommitVO;
+import com.sun.org.slf4j.internal.Logger;
+import com.sun.org.slf4j.internal.LoggerFactory;
+import okhttp3.*;
+import org.gitlab4j.api.models.AccessLevel;
+import org.gitlab4j.api.models.CommitAction;
+import org.gitlab4j.api.models.Visibility;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static com.nju.edu.gitlab.SeecoderGitlabException.BIZ_ERROR_CODE;
+
+public class SeecoderGitlabClient implements SeecoderGitlabApi{
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    private OkHttpClient client;
+    private String host;
+    private String token;
+
+    public SeecoderGitlabClient(String host,String token){
+        this.token=token;
+        this.host=host;
+        this.client=new OkHttpClient.Builder()
+                .connectTimeout(60, TimeUnit.SECONDS)
+                .writeTimeout(60,TimeUnit.SECONDS)
+                .retryOnConnectionFailure(true)
+                .build();
+    }
+
+    private <T> T processResponse(ObjectMapper objectMapper, Response response, Class<T> clazz) throws SeecoderGitlabException {
+        try {
+            validateResponseStatus(response);
+            String body = response.body().string();
+            JsonNode node = objectMapper.readTree(body);
+            Integer code = Integer.parseInt(node.get("code").asText());
+            String msg = node.get("msg").asText();
+            if (code != 0) {
+                throw new SeecoderGitlabException(BIZ_ERROR_CODE, msg);
+            }
+            if (clazz == null) {
+                return null;
+            }
+            if (node.get("result")!=null)
+                return objectMapper.treeToValue(node.get("result"), clazz);
+            else
+                throw SeecoderGitlabException.NOT_FOUND_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    private void validateResponseStatus(Response response) throws SeecoderGitlabException {
+        if (response.code() == 403) {
+            throw SeecoderGitlabException.UNAHTORIZATION_ERROR;
+        } else if (response.code() == 500) {
+            throw SeecoderGitlabException.INTERNAL_SERVER_ERROR;
+        } else if (response.code() != 200) {
+            throw SeecoderGitlabException.UNKNOWN_ERROR;
+        }
+    }
+
+    @Override
+    public GitlabUser createGitlabUser(String username, String password, String email) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            GitlabUserDTO gitlabUserDTO=GitlabUserDTO.builder()
+                                                    .email(email)
+                                                    .password(password)
+                                                    .username(username)
+                                                    .build();
+            builder = builder
+                    .url(host + "/api/user")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(gitlabUserDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            GitlabUser gitlabUser = processResponse(objectMapper, response, GitlabUser.class);
+            return gitlabUser;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public boolean changePassword(int userId, String password) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            ChangePasswordDTO changePasswordDTO=ChangePasswordDTO.builder()
+                                                                .password(password)
+                                                                .userId(userId)
+                                                                .build();
+            builder = builder
+                    .url(host + "/api/user/changePassword")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(changePasswordDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            boolean isChanged = processResponse(objectMapper, response, boolean.class);
+            return isChanged;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public boolean deleteUser(int userId) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            builder = builder
+                    .url(host + "/api/user/"+userId)
+                    .delete();
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            boolean isDeleted = processResponse(objectMapper, response, boolean.class);
+            return isDeleted;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public GitlabGroup createGroup(String groupName) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            builder = builder
+                    .url(host + "/api/user")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), groupName));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            GitlabGroup gitlabGroup = processResponse(objectMapper, response, GitlabGroup.class);
+            return gitlabGroup;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public boolean addMember(int groupId, int userId, AccessLevelForm accessLevelForm) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            AccessLevel accessLevel=AccessLevel.forValue(accessLevelForm.value);
+            GroupMemberDTO groupMemberDTO=GroupMemberDTO.builder()
+                                                        .accessLevel(accessLevel)
+                                                        .userId(userId)
+                                                        .groupId(groupId)
+                                                        .build();
+            builder = builder
+                    .url(host + "/api/group/addMember")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(groupMemberDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            boolean isAdded = processResponse(objectMapper, response, boolean.class);
+            return isAdded;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public Integer createProject(String projectName, VisibilityForm visibilityForm) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            Visibility visibility=Visibility.forValue(visibilityForm.toString());
+            ProjectDTO projectDTO= ProjectDTO.builder()
+                                            .projectName(projectName)
+                                            .visibility(visibility)
+                                            .build();
+            builder = builder
+                    .url(host + "/api/project")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(projectDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            return processResponse(objectMapper, response, Integer.class);
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public Integer forkProject(int projectId, int userId) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            UserForkDTO userForkDTO= UserForkDTO.builder()
+                    .projectId(projectId)
+                    .userId(userId)
+                    .build();
+            builder = builder
+                    .url(host + "/api/project/userFork")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(userForkDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            projectId = processResponse(objectMapper, response, Integer.class);
+            return projectId;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public Integer forkGroupProject(int projectId, int groupId) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            GroupForkDTO groupForkDTO= GroupForkDTO.builder()
+                    .projectId(projectId)
+                    .groupId(groupId)
+                    .build();
+            builder = builder
+                    .url(host + "/api/project/groupFork")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(groupForkDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            projectId = processResponse(objectMapper, response, Integer.class);
+            return projectId;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public Set<DiffVO> compare(int projectId, String fromBash, String toBash) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            builder = builder
+                    .url(host + "/api/project/compare?projectId="+projectId+"&fromBash="+fromBash+"&toBash="+toBash)
+                    .get();
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            Set<DiffVO> diffVOSet= new HashSet<>();
+            diffVOSet=processResponse(objectMapper, response, diffVOSet.getClass());
+            return diffVOSet;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public boolean addWebHook(int projectId, String url, boolean doPushEvents, boolean doIssueEvents, boolean doMergeRequestsEvents) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            WebHookDTO webHookDTO= WebHookDTO.builder()
+                                    .projectId(projectId)
+                                    .url(url)
+                                    .doIssueEvents(doIssueEvents)
+                                    .doPushEvents(doPushEvents)
+                                    .doMergeRequestsEvents(doMergeRequestsEvents)
+                                    .build();
+            builder = builder
+                    .url(host + "/api/project/webhook")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(webHookDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            return processResponse(objectMapper, response, boolean.class);
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public boolean archiveProject(int projectId) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            builder = builder
+                    .url(host + "/api/project/archive")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(projectId)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            return processResponse(objectMapper, response, boolean.class);
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public String getProjectFile(int projectId, String branch, String path) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            ProjectFileDTO projectFileDTO=ProjectFileDTO.builder()
+                                                    .path(path)
+                                                    .branch(branch)
+                                                    .build();
+            builder = builder
+                    .url(host + "/api/project/"+projectId+"/getFile")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(projectFileDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            return processResponse(objectMapper, response, String.class);
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public String getProjectRawFile(int projectId, String commitOrBranchName, String path) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            ProjectRawFileDTO projectFileDTO=ProjectRawFileDTO.builder()
+                                                .commitOrBranchName(commitOrBranchName)
+                                                .path(path)
+                                                .build();
+            builder = builder
+                    .url(host + "/api/project/"+projectId+"/getRawFile")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(projectFileDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            return processResponse(objectMapper, response, String.class);
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public CommitVO createCommit(int projectId, String branch, String commitMessage, String email, String username, List<CommitActionForm> actions) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            List<CommitAction> actionList=actions.stream().map(action-> new CommitAction()
+                                .withAction(CommitAction.Action.forValue(action.getAction().toString()))
+                                .withEncoding(CommitAction.Encoding.forValue(action.getEncoding().toString()))
+                                .withFilePath(action.getFilepath())
+                                .withContent(action.getContent())).collect(Collectors.toList());
+            CommitDTO commitDTO=CommitDTO.builder()
+                                        .branch(branch)
+                                        .commitMessage(commitMessage)
+                                        .email(email)
+                                        .username(username)
+                                        .actions(actionList)
+                                        .build();
+            builder = builder
+                    .url(host + "/api/project/"+projectId+"/commit")
+                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), objectMapper.writeValueAsString(commitDTO)));
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            return processResponse(objectMapper, response, CommitVO.class);
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public List<CommitVO> getAllCommitMessage(int projectId, String commitHash) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            builder = builder
+                    .url(host + "/api/project/"+projectId+"/commit/"+commitHash)
+                    .get();
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            List<CommitVO> commitVOList=new ArrayList<>();
+            commitVOList=processResponse(objectMapper, response, commitVOList.getClass());
+            return commitVOList;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+
+    @Override
+    public List<BranchVO> getProjectBranches(int projectId) throws SeecoderGitlabException {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            Request.Builder builder = new Request.Builder()
+                    .addHeader("Authorization", token);
+            builder = builder
+                    .url(host + "/api/project/"+projectId+"/branches")
+                    .get();
+            Request request = builder.build();
+            final Call call = client.newCall(request);
+            Response response = call.execute();
+            List<BranchVO> branchVOList=new ArrayList<>();
+            branchVOList=processResponse(objectMapper, response, branchVOList.getClass());
+            return branchVOList;
+        } catch (JsonProcessingException e) {
+            logger.error("JSON writeValueAsString error", e);
+            throw SeecoderGitlabException.JSON_ERROR;
+        } catch (IOException e) {
+            logger.error("IOException", e);
+            throw SeecoderGitlabException.IO_ERROR;
+        }
+    }
+}

+ 34 - 0
seecoder-gitlab-client/src/main/java/com.nju.edu.gitlab/SeecoderGitlabException.java

@@ -0,0 +1,34 @@
+package com.nju.edu.gitlab;
+
+public class SeecoderGitlabException extends Exception{
+
+    public static final SeecoderGitlabException UNKNOWN_ERROR = new SeecoderGitlabException("-1", "Unknown Error");
+
+    public static final SeecoderGitlabException JSON_ERROR = new SeecoderGitlabException("101", "JSON Processing Error");
+
+    public static final SeecoderGitlabException IO_ERROR = new SeecoderGitlabException("102", "Execute IO Error");
+
+    public static final SeecoderGitlabException UNAHTORIZATION_ERROR = new SeecoderGitlabException("403", "Unauthorization Error");
+
+    public static final SeecoderGitlabException NOT_FOUND_ERROR = new SeecoderGitlabException("404", "Not Found Error");
+
+    public static final SeecoderGitlabException INTERNAL_SERVER_ERROR = new SeecoderGitlabException("500", "Internal Server Error");
+
+    public static final String BIZ_ERROR_CODE = "100";
+
+    private String code;
+
+    private String msg;
+
+    public SeecoderGitlabException(String code, String msg) {
+        super(msg);
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public SeecoderGitlabException(String code, String msg, Throwable cause) {
+        super(msg, cause);
+        this.code = code;
+        this.msg = msg;
+    }
+}

+ 18 - 0
seecoder-gitlab-client/src/test/java/GitlabClientTest.java

@@ -0,0 +1,18 @@
+import okhttp3.OkHttpClient;
+import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.TimeUnit;
+
+public class GitlabClientTest {
+
+    @Test
+    public void testHttp(){
+        OkHttpClient client=new OkHttpClient.Builder()
+                .connectTimeout(60, TimeUnit.SECONDS)
+                .writeTimeout(60,TimeUnit.SECONDS)
+                .retryOnConnectionFailure(true)
+                .build();
+
+
+    }
+}

+ 26 - 0
seecoder-gitlab-common/pom.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>seecoder-gitlab</artifactId>
+        <groupId>com.nju.edu</groupId>
+        <version>0.1.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>seecoder-gitlab-common</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.gitlab4j</groupId>
+            <artifactId>gitlab4j-api</artifactId>
+            <version>4.8.7</version>
+        </dependency>
+    </dependencies>
+</project>

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/ChangePasswordDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/ChangePasswordDTO.java

@@ -1,10 +1,12 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class ChangePasswordDTO {

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/GitlabUserDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/GitlabUserDTO.java

@@ -1,10 +1,12 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class GitlabUserDTO {

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/GroupForkDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/GroupForkDTO.java

@@ -1,10 +1,12 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class GroupForkDTO {

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/ProjectFileDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/ProjectFileDTO.java

@@ -1,10 +1,12 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class ProjectFileDTO {

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/ProjectRawFileDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/ProjectRawFileDTO.java

@@ -1,10 +1,12 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class ProjectRawFileDTO {

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/UserForkDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/UserForkDTO.java

@@ -1,10 +1,12 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class UserForkDTO {

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/WebHookDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/WebHookDTO.java

@@ -1,10 +1,12 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class WebHookDTO {

+ 25 - 0
seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/commit/CommitActionForm.java

@@ -0,0 +1,25 @@
+package com.nju.edu.gitlab.dto.commit;
+
+import lombok.Data;
+
+@Data
+public class CommitActionForm {
+
+    public enum Action {
+        CREATE,
+        DELETE,
+        MOVE,
+        UPDATE
+    }
+
+    public enum Encoding{
+        BASE64,
+        TEXT
+    }
+
+
+    private Action action;
+    private Encoding encoding;
+    private String filepath;
+    private String content;
+}

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/CommitDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/commit/CommitDTO.java

@@ -1,6 +1,7 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto.commit;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.gitlab4j.api.models.CommitAction;
@@ -8,6 +9,7 @@ import org.gitlab4j.api.models.CommitAction;
 import java.util.List;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class CommitDTO {

+ 11 - 0
seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/member/AccessLevelForm.java

@@ -0,0 +1,11 @@
+package com.nju.edu.gitlab.dto.member;
+
+public enum  AccessLevelForm {
+    NONE(0), GUEST(10), REPORTER(20), DEVELOPER(30), MASTER(40), OWNER(50);
+
+    public final Integer value;
+
+    AccessLevelForm(int value) {
+        this.value = value;
+    }
+}

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/GroupMemberDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/member/GroupMemberDTO.java

@@ -1,11 +1,13 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto.member;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.gitlab4j.api.models.AccessLevel;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class GroupMemberDTO {

+ 3 - 1
src/main/java/com/nju/edu/gitlab/web/dto/ProjectDTO.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/project/ProjectDTO.java

@@ -1,11 +1,13 @@
-package com.nju.edu.gitlab.web.dto;
+package com.nju.edu.gitlab.dto.project;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.gitlab4j.api.models.Visibility;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class ProjectDTO {

+ 10 - 0
seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/dto/project/VisibilityForm.java

@@ -0,0 +1,10 @@
+package com.nju.edu.gitlab.dto.project;
+
+public enum VisibilityForm {
+    PUBLIC, PRIVATE, INTERNAL;
+
+    @Override
+    public String toString(){
+        return String.valueOf(this);
+    }
+}

+ 16 - 0
seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/BranchVO.java

@@ -0,0 +1,16 @@
+package com.nju.edu.gitlab.vo;
+
+import com.nju.edu.gitlab.vo.commit.CommitVO;
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class BranchVO {
+    private CommitVO commit;
+    private Boolean developersCanMerge;
+    private Boolean developersCanPush;
+    private Boolean merged;
+    private String name;
+    private Boolean isProtected;
+}

+ 19 - 0
seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/DiffVO.java

@@ -0,0 +1,19 @@
+package com.nju.edu.gitlab.vo;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class DiffVO {
+
+    private String a_mode;
+    private String b_mode;
+    private boolean deletedFile;
+    private String diff;
+    private boolean newFile;
+    private String newPath;
+    private String oldPath;
+    private boolean renamedFile;
+
+}

+ 1 - 1
src/main/java/com/nju/edu/gitlab/service/vo/GitlabGroup.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/GitlabGroup.java

@@ -1,4 +1,4 @@
-package com.nju.edu.gitlab.service.vo;
+package com.nju.edu.gitlab.vo;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;

+ 1 - 1
src/main/java/com/nju/edu/gitlab/service/vo/GitlabUser.java → seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/GitlabUser.java

@@ -1,4 +1,4 @@
-package com.nju.edu.gitlab.service.vo;
+package com.nju.edu.gitlab.vo;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;

+ 19 - 0
seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/commit/CommitStatsVO.java

@@ -0,0 +1,19 @@
+package com.nju.edu.gitlab.vo.commit;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.gitlab4j.api.models.CommitStats;
+
+@Data
+@AllArgsConstructor
+public class CommitStatsVO {
+    private Integer additions;
+    private Integer deletions;
+    private Integer total;
+
+    public CommitStatsVO(CommitStats stats) {
+        this.additions=stats.getAdditions();
+        this.deletions= stats.getDeletions();
+        this.total=stats.getTotal();
+    }
+}

+ 30 - 0
seecoder-gitlab-common/src/main/java/com/nju/edu/gitlab/vo/commit/CommitVO.java

@@ -0,0 +1,30 @@
+package com.nju.edu.gitlab.vo.commit;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+@Builder
+public class CommitVO {
+    private String branch;
+    private String author;
+    private Date authoredDate;
+    private String authorEmail;
+    private String authorName;
+    private Date committedDate;
+    private String committerEmail;
+    private String committerName;
+    private Date createdAt;
+    private String id;
+    private String message;
+    private List<String> parentIds;
+    private String shortId;
+    private CommitStatsVO stats;
+    private String status;
+    private Date timestamp;
+    private String title;
+    private String url;
+}

+ 93 - 0
seecoder-gitlab-server/pom.xml

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>seecoder-gitlab</artifactId>
+        <groupId>com.nju.edu</groupId>
+        <version>0.1.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>seecoder-gitlab-server</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.thymeleaf.extras</groupId>
+            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.gitlab4j</groupId>
+            <artifactId>gitlab4j-api</artifactId>
+            <version>4.8.7</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.20</version>
+        </dependency>
+        <dependency>
+            <groupId>com.nju.edu</groupId>
+            <artifactId>seecoder-gitlab-common</artifactId>
+            <version>0.1.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 0 - 0
src/main/java/com/nju/edu/gitlab/GitlabApplication.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/GitlabApplication.java


+ 2 - 3
src/main/java/com/nju/edu/gitlab/controller/GitlabGroupController.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/controller/GitlabGroupController.java

@@ -1,8 +1,7 @@
 package com.nju.edu.gitlab.controller;
 
 import com.nju.edu.gitlab.service.api.GroupService;
-import com.nju.edu.gitlab.web.dto.GroupMemberDTO;
-import com.nju.edu.gitlab.web.response.EmptyResponse;
+import com.nju.edu.gitlab.dto.member.GroupMemberDTO;
 import com.nju.edu.gitlab.web.response.ResourceResponse;
 import com.nju.edu.gitlab.web.response.Response;
 import org.gitlab4j.api.GitLabApiException;
@@ -21,7 +20,7 @@ public class GitlabGroupController {
     }
 
     @PostMapping("/")
-    public Response createGitlabGroup(@RequestParam String groupName) throws GitLabApiException {
+    public Response createGitlabGroup(@RequestBody String groupName) throws GitLabApiException {
         return new ResourceResponse(groupService.createGroup(groupName));
     }
 

+ 6 - 4
src/main/java/com/nju/edu/gitlab/controller/GitlabProjectController.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/controller/GitlabProjectController.java

@@ -1,7 +1,9 @@
 package com.nju.edu.gitlab.controller;
 
+import com.nju.edu.gitlab.dto.commit.CommitDTO;
+import com.nju.edu.gitlab.dto.project.ProjectDTO;
 import com.nju.edu.gitlab.service.api.ProjectService;
-import com.nju.edu.gitlab.web.dto.*;
+import com.nju.edu.gitlab.dto.*;
 import com.nju.edu.gitlab.web.response.EmptyResponse;
 import com.nju.edu.gitlab.web.response.ResourceResponse;
 import com.nju.edu.gitlab.web.response.Response;
@@ -50,7 +52,7 @@ public class GitlabProjectController {
     }
 
     @PostMapping("/archive")
-    public Response archiveProject(@RequestParam Integer projectId) throws GitLabApiException {
+    public Response archiveProject(@RequestBody Integer projectId) throws GitLabApiException {
         return new ResourceResponse(projectService.archiveProject(projectId));
     }
 
@@ -59,13 +61,13 @@ public class GitlabProjectController {
         return new EmptyResponse();
     }
 
-    @GetMapping("/{projectId}/getFile")
+    @PostMapping("/{projectId}/getFile")
     public Response getProjectFile(@PathVariable(name = "projectId") Integer projectId,
                                    @RequestBody ProjectFileDTO projectFileDTO) throws UnsupportedEncodingException, GitLabApiException {
         return new ResourceResponse(projectService.getProjectFile(projectId,projectFileDTO));
     }
 
-    @GetMapping("/{projectId}/getRawFile")
+    @PostMapping("/{projectId}/getRawFile")
     public Response getProjectRawFile(@PathVariable(name = "projectId") Integer projectId,
                                       @RequestBody ProjectRawFileDTO projectRawFileDTO) throws GitLabApiException, IOException {
         return new ResourceResponse(projectService.getProjectRawFile(projectId,projectRawFileDTO));

+ 2 - 3
src/main/java/com/nju/edu/gitlab/controller/GitlabUserController.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/controller/GitlabUserController.java

@@ -1,9 +1,8 @@
 package com.nju.edu.gitlab.controller;
 
 import com.nju.edu.gitlab.service.api.UserService;
-import com.nju.edu.gitlab.web.dto.ChangePasswordDTO;
-import com.nju.edu.gitlab.web.dto.GitlabUserDTO;
-import com.nju.edu.gitlab.web.response.EmptyResponse;
+import com.nju.edu.gitlab.dto.ChangePasswordDTO;
+import com.nju.edu.gitlab.dto.GitlabUserDTO;
 import com.nju.edu.gitlab.web.response.ResourceResponse;
 import com.nju.edu.gitlab.web.response.Response;
 import org.gitlab4j.api.GitLabApiException;

+ 2 - 2
src/main/java/com/nju/edu/gitlab/service/api/GroupService.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/api/GroupService.java

@@ -1,7 +1,7 @@
 package com.nju.edu.gitlab.service.api;
 
-import com.nju.edu.gitlab.service.vo.GitlabGroup;
-import com.nju.edu.gitlab.web.dto.GroupMemberDTO;
+import com.nju.edu.gitlab.vo.GitlabGroup;
+import com.nju.edu.gitlab.dto.member.GroupMemberDTO;
 import org.gitlab4j.api.GitLabApiException;
 
 public interface GroupService {

+ 10 - 8
src/main/java/com/nju/edu/gitlab/service/api/ProjectService.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/api/ProjectService.java

@@ -1,10 +1,12 @@
 package com.nju.edu.gitlab.service.api;
 
-import com.nju.edu.gitlab.web.dto.*;
+import com.nju.edu.gitlab.dto.*;
+import com.nju.edu.gitlab.dto.commit.CommitDTO;
+import com.nju.edu.gitlab.dto.project.ProjectDTO;
+import com.nju.edu.gitlab.vo.BranchVO;
+import com.nju.edu.gitlab.vo.commit.CommitVO;
+import com.nju.edu.gitlab.vo.DiffVO;
 import org.gitlab4j.api.GitLabApiException;
-import org.gitlab4j.api.models.Branch;
-import org.gitlab4j.api.models.Commit;
-import org.gitlab4j.api.models.Diff;
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -19,7 +21,7 @@ public interface ProjectService {
 
     public Integer forkGroupProject(GroupForkDTO groupForkDTO) throws GitLabApiException;
 
-    public Set<Diff> compare(int projectId, String fromBash, String toBash) throws GitLabApiException;
+    public Set<DiffVO> compare(int projectId, String fromBash, String toBash) throws GitLabApiException;
 
     public boolean addWebHook(WebHookDTO webHookDTO) throws GitLabApiException;
 
@@ -29,9 +31,9 @@ public interface ProjectService {
 
     public String getProjectRawFile(int projectId, ProjectRawFileDTO projectRawFileDTO) throws GitLabApiException, IOException;
 
-    public Commit createCommit(int projectId, CommitDTO commitDTO) throws GitLabApiException;
+    public CommitVO createCommit(int projectId, CommitDTO commitDTO) throws GitLabApiException;
 
-    public List<Commit> getAllCommitMessage(int projectId,String commitHash) throws GitLabApiException;
+    public List<CommitVO> getAllCommitMessage(int projectId,String commitHash) throws GitLabApiException;
 
-    public List<Branch> getProjectBranches(int projectId) throws GitLabApiException;
+    public List<BranchVO> getProjectBranches(int projectId) throws GitLabApiException;
 }

+ 3 - 4
src/main/java/com/nju/edu/gitlab/service/api/UserService.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/api/UserService.java

@@ -1,10 +1,9 @@
 package com.nju.edu.gitlab.service.api;
 
-import com.nju.edu.gitlab.service.vo.GitlabUser;
-import com.nju.edu.gitlab.web.dto.ChangePasswordDTO;
-import com.nju.edu.gitlab.web.dto.GitlabUserDTO;
+import com.nju.edu.gitlab.vo.GitlabUser;
+import com.nju.edu.gitlab.dto.ChangePasswordDTO;
+import com.nju.edu.gitlab.dto.GitlabUserDTO;
 import org.gitlab4j.api.GitLabApiException;
-import org.gitlab4j.api.models.User;
 
 public interface UserService {
 

+ 2 - 3
src/main/java/com/nju/edu/gitlab/service/impl/GroupServiceImpl.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/impl/GroupServiceImpl.java

@@ -1,16 +1,15 @@
 package com.nju.edu.gitlab.service.impl;
 
 import com.nju.edu.gitlab.service.api.GroupService;
-import com.nju.edu.gitlab.service.vo.GitlabGroup;
+import com.nju.edu.gitlab.vo.GitlabGroup;
 import com.nju.edu.gitlab.util.ApplicationProperties;
-import com.nju.edu.gitlab.web.dto.GroupMemberDTO;
+import com.nju.edu.gitlab.dto.member.GroupMemberDTO;
 import org.gitlab4j.api.GitLabApi;
 import org.gitlab4j.api.GitLabApiException;
 import org.gitlab4j.api.models.AccessLevel;
 import org.gitlab4j.api.models.Group;
 import org.gitlab4j.api.models.Namespace;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 @Component

+ 75 - 15
src/main/java/com/nju/edu/gitlab/service/impl/ProjectServiceImpl.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/impl/ProjectServiceImpl.java

@@ -1,20 +1,22 @@
 package com.nju.edu.gitlab.service.impl;
 
+import com.nju.edu.gitlab.dto.commit.CommitDTO;
+import com.nju.edu.gitlab.dto.project.ProjectDTO;
 import com.nju.edu.gitlab.service.api.ProjectService;
 import com.nju.edu.gitlab.util.ApplicationProperties;
-import com.nju.edu.gitlab.web.dto.*;
+import com.nju.edu.gitlab.dto.*;
+import com.nju.edu.gitlab.vo.BranchVO;
+import com.nju.edu.gitlab.vo.commit.CommitStatsVO;
+import com.nju.edu.gitlab.vo.commit.CommitVO;
+import com.nju.edu.gitlab.vo.DiffVO;
 import org.gitlab4j.api.GitLabApi;
 import org.gitlab4j.api.GitLabApiException;
 import org.gitlab4j.api.models.*;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import java.io.*;
-import java.util.Base64;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Component
@@ -92,9 +94,19 @@ public class ProjectServiceImpl implements ProjectService {
     }
 
     @Override
-    public Set<Diff> compare(int projectId, String fromBash, String toBash) throws GitLabApiException {
+    public Set<DiffVO> compare(int projectId, String fromBash, String toBash) throws GitLabApiException {
         CompareResults compareResults = gitlabApi.getRepositoryApi().compare(projectId, fromBash, toBash);
-        return new HashSet<>(compareResults.getDiffs());
+        List<Diff> diffs=compareResults.getDiffs();
+        Set<DiffVO> res=diffs.stream().map(diff -> DiffVO.builder()
+                .a_mode(diff.getAMode())
+                .b_mode(diff.getBMode())
+                .deletedFile(diff.getDeletedFile())
+                .newFile(diff.getNewFile())
+                .newPath(diff.getNewPath())
+                .oldPath(diff.getOldPath())
+                .renamedFile(diff.getRenamedFile())
+                .build()).collect(Collectors.toSet());
+        return res;
     }
 
     @Override
@@ -118,7 +130,7 @@ public class ProjectServiceImpl implements ProjectService {
     public String getProjectFile(int projectId,ProjectFileDTO projectFileDTO) throws UnsupportedEncodingException, GitLabApiException {
         String branch=projectFileDTO.getBranch();
         String path=projectFileDTO.getPath();
-        RepositoryFile repositoryFile = gitlabApi.getRepositoryFileApi().getFile(projectId, path,branch);
+        RepositoryFile repositoryFile = gitlabApi.getRepositoryFileApi().getFile(path,projectId,branch);
         if(repositoryFile!=null){
             return new String(Base64.getDecoder().decode(repositoryFile.getContent()), "UTF-8");
         }
@@ -146,24 +158,72 @@ public class ProjectServiceImpl implements ProjectService {
     }
 
     @Override
-    public Commit createCommit(int projectId, CommitDTO commitDTO) throws GitLabApiException {
+    public CommitVO createCommit(int projectId, CommitDTO commitDTO) throws GitLabApiException {
         String branch=commitDTO.getBranch();
         String commitMsg=commitDTO.getCommitMessage();
         String username=commitDTO.getUsername();
         String email=commitDTO.getEmail();
         List<CommitAction> actions=commitDTO.getActions();
         Commit commit=gitlabApi.getCommitsApi().createCommit(projectId,branch,commitMsg,null,email,username,actions);
-        return commit;
+        return castCommitToVO(commit,branch);
     }
 
+
+
     @Override
-    public List<Commit> getAllCommitMessage(int projectId, String commitHash) throws GitLabApiException {
-        return gitlabApi.getCommitsApi().getCommits(projectId,commitHash,null,null);
+    public List<CommitVO> getAllCommitMessage(int projectId, String commitHash) throws GitLabApiException {
+        Commit commit=gitlabApi.getCommitsApi().getCommit(projectId,commitHash);
+        List<Branch> branches=gitlabApi.getRepositoryApi().getBranches(projectId);
+        for (Branch branch:branches){
+            List<Commit> commits=gitlabApi.getCommitsApi().getCommits(projectId,branch.getName(),null,null);
+            if (commits.contains(commit)){
+                return commits.stream()
+                        .map(com -> castCommitToVO(commit,branch.getName()))
+                        .collect(Collectors.toList());
+            }
+        }
+        return Collections.emptyList();
+    }
+
+    private CommitVO castCommitToVO(Commit commit,String branch) {
+        return CommitVO.builder()
+                .branch(branch)
+                .author(String.valueOf(commit.getAuthor().getId()))
+                .authoredDate(commit.getAuthoredDate())
+                .authorEmail(commit.getAuthorEmail())
+                .authorName(commit.getAuthorName())
+                .committedDate(commit.getCommittedDate())
+                .committerEmail(commit.getCommitterEmail())
+                .committerName(commit.getCommitterName())
+                .createdAt(commit.getCreatedAt())
+                .id(commit.getId())
+                .message(commit.getMessage())
+                .parentIds(commit.getParentIds())
+                .shortId(commit.getShortId())
+                .stats(new CommitStatsVO(commit.getStats()))
+                .status(commit.getStatus())
+                .timestamp(commit.getTimestamp())
+                .title(commit.getTitle())
+                .url(commit.getUrl())
+                .build();
     }
 
     @Override
-    public List<Branch> getProjectBranches(int projectId) throws GitLabApiException {
-        return  gitlabApi.getRepositoryApi().getBranches(projectId);
+    public List<BranchVO> getProjectBranches(int projectId) throws GitLabApiException {
+        return gitlabApi.getRepositoryApi().getBranches(projectId).stream()
+                .map(branch -> castBranchToVO(branch))
+                .collect(Collectors.toList());
+    }
+
+    private BranchVO castBranchToVO(Branch branch) {
+        return BranchVO.builder()
+                .commit(castCommitToVO(branch.getCommit(),branch.getName()))
+                .developersCanMerge(branch.getDevelopersCanMerge())
+                .developersCanPush(branch.getDevelopersCanPush())
+                .merged(branch.getMerged())
+                .name(branch.getName())
+                .isProtected(branch.getProtected())
+                .build();
     }
 
 

+ 5 - 6
src/main/java/com/nju/edu/gitlab/service/impl/UserServiceImpl.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/service/impl/UserServiceImpl.java

@@ -1,17 +1,16 @@
 package com.nju.edu.gitlab.service.impl;
 
 import com.nju.edu.gitlab.service.api.UserService;
-import com.nju.edu.gitlab.service.vo.GitlabUser;
+import com.nju.edu.gitlab.vo.GitlabUser;
 import com.nju.edu.gitlab.util.ApplicationProperties;
 import com.nju.edu.gitlab.util.Tools;
-import com.nju.edu.gitlab.web.dto.ChangePasswordDTO;
-import com.nju.edu.gitlab.web.dto.GitlabUserDTO;
+import com.nju.edu.gitlab.dto.ChangePasswordDTO;
+import com.nju.edu.gitlab.dto.GitlabUserDTO;
 import org.gitlab4j.api.GitLabApi;
 import org.gitlab4j.api.GitLabApiException;
 import org.gitlab4j.api.models.*;
 import org.gitlab4j.api.models.ImpersonationToken.Scope;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 @Component
@@ -38,7 +37,7 @@ public class UserServiceImpl implements UserService {
         user.setUsername(username);
         user.setEmail(email);
         user.setSkipConfirmation(true);
-        user= gitlabApi.getUserApi().createUser(user, password, true);
+        user= gitlabApi.getUserApi().createUser(user, password, 1000);
         GitlabUser gitlabUser=new GitlabUser();
         gitlabUser.setUserId(user.getId());
         gitlabUser.setNamespaceId(fetchNameSpaceId(username));
@@ -51,7 +50,7 @@ public class UserServiceImpl implements UserService {
         int userId=changePasswordDTO.getUserId();
         String password=changePasswordDTO.getPassword();
         User user=gitlabApi.getUserApi().getUser(userId);
-        gitlabApi.getUserApi().updateUser(user,password);
+        gitlabApi.getUserApi().modifyUser(user,password,1000);
         return true;
     }
 

+ 0 - 0
src/main/java/com/nju/edu/gitlab/util/ApplicationProperties.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/util/ApplicationProperties.java


+ 0 - 0
src/main/java/com/nju/edu/gitlab/util/Tools.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/util/Tools.java


+ 1 - 1
src/main/java/com/nju/edu/gitlab/web/handler/ApiExceptionHandler.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/handler/ApiExceptionHandler.java

@@ -11,7 +11,7 @@ import javax.servlet.http.HttpServletResponse;
 
 @RestControllerAdvice("{com.nju.edu.gitlab.controller}")
 public class ApiExceptionHandler {
-    
+
     @ExceptionHandler(Exception.class)
     @ResponseBody
     public Response handle(HttpServletResponse response, Exception exception) {

+ 0 - 0
src/main/java/com/nju/edu/gitlab/web/response/EmptyResponse.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/response/EmptyResponse.java


+ 0 - 0
src/main/java/com/nju/edu/gitlab/web/response/ErrorResponse.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/response/ErrorResponse.java


+ 0 - 0
src/main/java/com/nju/edu/gitlab/web/response/ResourceResponse.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/response/ResourceResponse.java


+ 0 - 0
src/main/java/com/nju/edu/gitlab/web/response/Response.java → seecoder-gitlab-server/src/main/java/com/nju/edu/gitlab/web/response/Response.java


+ 0 - 0
src/main/resources/application.yml → seecoder-gitlab-server/src/main/resources/application.yml