一、背景
上文讲述了如何使用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组里的人员把你加入进组里。