Devops系列之对接Gerrit的设计与实现(三)-- Java编程实现

发布于:2025-04-15 ⋅ 阅读:(28) ⋅ 点赞:(0)

一、背景

上文讲述了如何使用shell命令实现创建gerrit项目,本文介绍如何使用java语言编程实现。

二、java语言实现

1、引入jar包

        <dependency>
            <groupId>com.urswolfer.gerrit.client.rest</groupId>
            <artifactId>gerrit-rest-java-client</artifactId>
            <version>0.9.3</version>
        </dependency>

核心类GroupApiRestClient.java

在这里插入图片描述

2、配置

project:
  gerrit:
    host: http://192.168.5.60:8080
    login: admin
    password: 123456
    # 负责人
    groupOwnerId: 34dd8f718972d73c9a3474b2sfad2d52x2cf596f

3、实现类

  • 配置类GerritProperties.java

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;

/**
 * gerrit配置
 *
 * @author xxx
 */
@RefreshScope
@Data
@Configuration
@ConfigurationProperties(prefix = "project.gerrit")
public class GerritProperties {
    /**
     * 地址
     */
    private String host;

    /**
     * 用户名
     */
    private String login;

    /**
     * 密码
     */
    private String password;

    /**
     * 所属的组ID
     */
    private String groupOwnerId;
}

  • 总体实现

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.access.AccessSectionInfo;
import com.google.gerrit.extensions.api.access.PermissionInfo;
import com.google.gerrit.extensions.api.access.PermissionRuleInfo;
import com.google.gerrit.extensions.api.access.ProjectAccessInput;
import com.google.gerrit.extensions.api.groups.GroupInput;
import com.google.gerrit.extensions.api.projects.ProjectApi;
import com.google.gerrit.extensions.api.projects.ProjectInput;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.GroupBaseInfo;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.common.ProjectInfo;
import com.urswolfer.gerrit.client.rest.GerritAuthData;
import com.urswolfer.gerrit.client.rest.GerritRestApiFactory;
import com.urswolfer.gerrit.client.rest.http.HttpStatusException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * gerrit api
 * <p>
 * 1.创建负责人组
 * 2.创建开发人组
 * 3.创建工程
 * 4.设置权限
 * </p>
 *
 * @author xxx
 */
@Slf4j
@Service
public class GerritService {

    private GerritRestApiFactory gerritRestApiFactory;
    private GerritAuthData.Basic authData;
    private GerritApi gerritApi;

    @Autowired
    private GerritProperties gerritProperties;

    @PostConstruct
    public void init() {
        gerritRestApiFactory = new GerritRestApiFactory();
        authData = new GerritAuthData.Basic(gerritProperties.getHost(), gerritProperties.getLogin(), gerritProperties.getPassword());
        gerritApi = gerritRestApiFactory.create(authData);
    }

    /**
     * 新建gerrit项目及组、权限
     *
     * @param group       项目组
     * @param projectName 项目名称,比如:root/watch-answering-server
     */
    public void create(String group, String projectName) {
        String ownerGroupName = projectName + "-owner";
        String devGroupName = projectName + "-dev";

        try {
            // 创建负责人分组
            GroupBaseInfo ownerGroupBaseInfo = this.createGroup(ownerGroupName, gerritProperties.getGroupOwnerId());
            String ownerGroupId = ownerGroupBaseInfo.id;
            log.info("负责人分组ID:{}", ownerGroupId);

            // 创建开发者分组
            GroupBaseInfo devGroupBaseInfo = this.createGroup(devGroupName, ownerGroupId);
            String devGroupId = devGroupBaseInfo.id;
            log.info("开发者分组ID:{}", devGroupId);

            // 创建工程
            ProjectInfo projectInfo = this.createProject(projectName, ownerGroupName);
            log.info("项目的详情是:{}", JsonUtils.toJsonString(projectInfo));

            // 赋权限项
            if (null != projectInfo) {
                this.setAccess(projectName, ownerGroupId, devGroupId);
            }
        } catch (Exception e) {
            log.error("创建组、工程、赋权出现了异常, projectName={}", projectName, e);
        }
    }
}

  • 创建组的实现代码
    /**
     * 创建组.
     *
     * @param groupName 组名
     * @param ownerId   所属组
     * @return
     * @throws Exception
     */
    private GroupBaseInfo createGroup(String groupName, String ownerId) throws Exception {
        GroupBaseInfo groupBaseInfo = new GroupBaseInfo();

        GroupInfo groupInfo;
        try {
            groupInfo = gerritApi.groups().id(groupName).get();
            log.warn("组{}已存在,请勿重复创建", groupName);
        } catch (HttpStatusException e) {
            // 不存在,则重新创建

            GroupInput groupInput = new GroupInput();
            groupInput.name = groupName;
            groupInput.description = groupName;
            groupInput.ownerId = ownerId;
            groupInput.visibleToAll = false;

            groupInfo = gerritApi.groups().create(groupInput).get();
            if (null == groupInfo) {
                throw new IllegalArgumentException("创建组出现异常");
            }

            log.info("组创建成功, groupInput={}", JsonUtils.toJsonString(groupInput));

            groupBaseInfo.id = groupInfo.id;
            groupBaseInfo.name = groupInfo.name;
            return groupBaseInfo;
        }

        groupBaseInfo.id = groupInfo.id;
        groupBaseInfo.name = groupInfo.name;
        return groupBaseInfo;
    }
  • 创建工程的实现代码
/**
     * 新建工程.
     *
     * @param projectName    工程名
     * @param ownerGroupName 所属组
     * @return
     * @throws Exception
     */
    private ProjectInfo createProject(String projectName, String ownerGroupName) throws Exception {
        try {
            ProjectApi projectApi = gerritApi.projects().name(projectName);

            ProjectInfo projectInfo = projectApi.get();
            if (null != projectInfo) {
                log.warn("工程{}已存在,请勿重复创建", projectName);
                return projectInfo;
            }
        } catch (Exception e) {
            ProjectInput request = new ProjectInput();
            request.name = projectName;
            request.description = projectName;
            request.submitType = SubmitType.INHERIT;
            request.owners = Lists.newArrayList(ownerGroupName);

            log.info("新建gerrit工程成功, request={}", JsonUtils.toJsonString(request));

            return gerritApi.projects().create(request).get();
        }

        return null;
    }
  • 赋权限的实现代码

   
    /**
     * 赋权限.
     *
     * @param projectName  项目名称
     * @param ownerGroupId 负责人组ID
     * @param devGroupId   开发组ID
     * @throws Exception
     */
    private void setAccess(String projectName, String ownerGroupId, String devGroupId) throws Exception {
        try {
            ProjectApi projectApi = gerritApi.projects().name(projectName);

            ProjectAccessInput projectAccessInput = new ProjectAccessInput();
            Map<String, AccessSectionInfo> addMap = Maps.newHashMap();
            addMap.put("refs/*", buildAccessSectionInfo(ownerGroupId, devGroupId));
            addMap.put("refs/tags/*", buildTagsAccessSectionInfo(devGroupId));
            addMap.put("refs/heads/*", buildHeadsAccessSectionInfo(ownerGroupId, devGroupId));

            log.info("权限列表是:{}", JsonUtils.toJsonString(addMap));

            projectAccessInput.add = addMap;

            projectApi.access(projectAccessInput);
        } catch (HttpStatusException e) {
            log.error("赋权限出现异常, projectName={}, ownerGroupId={}, devGroupId={}", projectName, ownerGroupId, devGroupId, e);
        }
    }


    private AccessSectionInfo buildAccessSectionInfo(String ownerGroupId, String devGroupId) {
        AccessSectionInfo accessSectionInfo = new AccessSectionInfo();

        Map<String, PermissionInfo> permissions = Maps.newHashMap();

        permissions.put("read", buildPermissionInfo("", devGroupId));
        permissions.put("label-Code-Review", buildReviewPermissionInfo("Code-Review", ownerGroupId, devGroupId));
        permissions.put("label-Verified", buildReviewPermissionInfo("Verified", ownerGroupId, devGroupId));
        permissions.put("labelAs-Verified", buildReviewPermissionInfo("Verified", ownerGroupId, devGroupId));
        permissions.put("forgeServerAsCommitter", buildPermissionInfo("", ownerGroupId, devGroupId));
        permissions.put("forgeAuthor", buildPermissionInfo("", ownerGroupId, devGroupId));
        permissions.put("removeReviewer", buildPermissionInfo("", ownerGroupId, devGroupId));
        permissions.put("delete", buildPermissionInfo("", ownerGroupId));
        permissions.put("viewPrivateChanges", buildPermissionInfo("", ownerGroupId));
        permissions.put("createTag", buildPermissionInfo("", ownerGroupId));
        permissions.put("createSignedTag", buildPermissionInfo("", ownerGroupId));
        permissions.put("editHashtags", buildPermissionInfo("", ownerGroupId));
        permissions.put("deleteOwnChanges", buildPermissionInfo("", devGroupId));
        permissions.put("editTopicName", buildPermissionInfo("", devGroupId));
        permissions.put("abandon", buildPermissionInfo("", devGroupId));
        permissions.put("push", buildPermissionInfo("", devGroupId));
        permissions.put("addPatchSet", buildPermissionInfo("", devGroupId));
        permissions.put("forgeCommitter", buildPermissionInfo("", devGroupId));
        permissions.put("pushMerge", buildPermissionInfo("", devGroupId));
        permissions.put("rebase", buildPermissionInfo("", devGroupId));
        permissions.put("submit", buildPermissionInfo("", ownerGroupId));
        permissions.put("submitAs", buildPermissionInfo("", ownerGroupId));

        accessSectionInfo.permissions = permissions;

        return accessSectionInfo;
    }

    private AccessSectionInfo buildTagsAccessSectionInfo(String devGroupId) {
        AccessSectionInfo accessSectionInfo = new AccessSectionInfo();

        Map<String, PermissionInfo> permissions = Maps.newHashMap();

        permissions.put("createSignedTag", buildPermissionInfo("", devGroupId));
        permissions.put("createTag", buildPermissionInfo("", devGroupId));

        accessSectionInfo.permissions = permissions;

        return accessSectionInfo;
    }

    private AccessSectionInfo buildHeadsAccessSectionInfo(String ownerGroupId, String devGroupId) {
        AccessSectionInfo accessSectionInfo = new AccessSectionInfo();

        Map<String, PermissionInfo> permissions = Maps.newHashMap();

        permissions.put("forgeCommitter", buildPermissionInfo("", devGroupId));
        permissions.put("label-Code-Review", buildReviewPermissionInfo("Code-Review", ownerGroupId, devGroupId));
        permissions.put("forgeAuthor", buildPermissionInfo("", devGroupId));
        permissions.put("editTopicName", buildPermissionInfo("", devGroupId));
        permissions.put("create", buildPermissionInfo("", devGroupId));
        permissions.put("push", buildPermissionInfo("", devGroupId));
        permissions.put("submit", buildPermissionInfo("", ownerGroupId));

        accessSectionInfo.permissions = permissions;

        return accessSectionInfo;
    }

    private PermissionInfo buildPermissionInfo(String label, String groupId) {
        PermissionInfo permissionInfo = new PermissionInfo(label, false);

        Map<String, PermissionRuleInfo> rules = buildRules(groupId);
        permissionInfo.rules = rules;

        return permissionInfo;
    }

    private PermissionInfo buildPermissionInfo(String label, String ownerGroupId, String devGroupId) {
        PermissionInfo permissionInfo = new PermissionInfo(label, false);

        Map<String, PermissionRuleInfo> rules = buildRules(ownerGroupId, devGroupId);
        permissionInfo.rules = rules;

        return permissionInfo;
    }

    private PermissionInfo buildReviewPermissionInfo(String label, String ownerGroupId, String devGroupId) {
        PermissionInfo permissionInfo = new PermissionInfo(label, false);

        Map<String, PermissionRuleInfo> rules = buildReviewRules(ownerGroupId, devGroupId);
        permissionInfo.rules = rules;

        return permissionInfo;
    }

    private Map<String, PermissionRuleInfo> buildRules(String groupId) {
        Map<String, PermissionRuleInfo> rules = Maps.newHashMap();

        PermissionRuleInfo permissionRuleInfo = buildPermissionRuleInfo();
        rules.put(groupId, permissionRuleInfo);

        return rules;
    }

    private Map<String, PermissionRuleInfo> buildRules(String ownerGroupId, String devGroupId) {
        Map<String, PermissionRuleInfo> rules = Maps.newHashMap();

        PermissionRuleInfo permissionRuleInfo = buildPermissionRuleInfo();
        rules.put(ownerGroupId, permissionRuleInfo);
        rules.put(devGroupId, permissionRuleInfo);

        return rules;
    }

    private Map<String, PermissionRuleInfo> buildReviewRules(String ownerGroupId, String devGroupId) {
        Map<String, PermissionRuleInfo> rules = Maps.newHashMap();

        PermissionRuleInfo permissionRuleInfo = buildPermissionRuleInfo();
        permissionRuleInfo.max = 2;
        permissionRuleInfo.min = -2;
        rules.put(ownerGroupId, permissionRuleInfo);

        permissionRuleInfo = buildPermissionRuleInfo();
        permissionRuleInfo.max = 1;
        permissionRuleInfo.min = -1;
        rules.put(devGroupId, permissionRuleInfo);

        return rules;
    }

    private PermissionRuleInfo buildPermissionRuleInfo() {
        PermissionRuleInfo permissionRuleInfo = new PermissionRuleInfo(PermissionRuleInfo.Action.ALLOW, false);

        return permissionRuleInfo;
    }

三、测试

    @Autowired
    private GerritService gerritService;

    @ApiOperation(value = "新建gerrit工程")
    @PostMapping(value = "/api/gerrit/create/{projectName}")
    public ResponseEntity<?> createProject(@NotNull @PathVariable String projectName) {

        // 新建gerrit工程
        gerritService.create("", "root/" + projectName);

        return ResponseEntity.ok("SUCCESS");
    }

四、写在最后的话

截止到目前,对接gerrit的设计与详细实现均已完整梳理,后文将解决代码提交的消息提醒。

本文只实现了自动创建gerrit项目以及权限项,创建了owner组和dev组。因为缺少信息–每个组里应该添加哪些人。
后期将实现给组里加人的操作。

也就是说,gerrit工程创建后,申请新项目的人,如果不在上面的owner组内,你会看不到已创建好的gerrti工程!!

不要慌,让owner组里的人员把你加入进组里。


网站公告

今日签到

点亮在社区的每一天
去签到