一、概述
配置项也称为
item
,是Namespace
下最小颗粒度的单位
创建一个item的流程
二、页面流程
这里我们在页面上创建一个配置项
会请求后台的item接口
2.代码流程
- 看下
portal
模块下的ItemController#createItem
方法
这里首先做操作校验,然后调用
releaseService.publish
方法发布配置,最后广播出去事件
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)")
@PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/releases")
public ReleaseDTO createRelease(@PathVariable String appId,
@PathVariable String env, @PathVariable String clusterName,
@PathVariable String namespaceName, @RequestBody NamespaceReleaseModel model) {
model.setAppId(appId);
model.setEnv(env);
model.setClusterName(clusterName);
model.setNamespaceName(namespaceName);
//若是紧急发布,但是当前环境未允许该操作,抛出异常
if (model.isEmergencyPublish() && !portalConfig.isEmergencyPublishAllowed(Env.valueOf(env))) {
throw new BadRequestException(String.format("Env: %s is not supported emergency publish now", env));
}
//发布配置
ReleaseDTO createdRelease = releaseService.publish(model);
//创建 ConfigPublishEvent 对象
ConfigPublishEvent event = ConfigPublishEvent.instance();
event.withAppId(appId)
.withCluster(clusterName)
.withNamespace(namespaceName)
.withReleaseId(createdRelease.getId())
.setNormalPublishEvent(true)
.setEnv(Env.valueOf(env));
//发布 ConfigPublishEvent 对象
publisher.publishEvent(event);
return createdRelease;
}
ReleaseService#publish
方法
这里发现直接通过
http
调用AdminService
来发布配置项
public ReleaseDTO publish(NamespaceReleaseModel model) {
Env env = model.getEnv();
boolean isEmergencyPublish = model.isEmergencyPublish();
String appId = model.getAppId();
String clusterName = model.getClusterName();
String namespaceName = model.getNamespaceName();
String releaseBy = StringUtils.isEmpty(model.getReleasedBy()) ?
userInfoHolder.getUser().getUserId() : model.getReleasedBy();
// 调用 Admin Service API, 发布 Namespace 的配置
ReleaseDTO releaseDTO = releaseAPI.createRelease(appId, env, clusterName, namespaceName,
model.getReleaseTitle(), model.getReleaseComment(),
releaseBy, isEmergencyPublish);
Tracer.logEvent(TracerEventType.RELEASE_NAMESPACE,
String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName));
return releaseDTO;
}
adminService
模块下的ItemController#create
方法
这里发现不仅保存了Item对象,还创建了一个commit对象进行保存,这个commit就是记录了每次操作的变更,方便重要数据的变更进行回溯。
@PreAcquireNamespaceLock
@PostMapping("/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items")
public ItemDTO create(@PathVariable("appId") String appId,
@PathVariable("clusterName") String clusterName,
@PathVariable("namespaceName") String namespaceName, @RequestBody ItemDTO dto) {
// 将 ItemDTO 转换成 Item 对象
Item entity = BeanUtils.transform(Item.class, dto);
//创建 ConfigChangeContentBuilder 对象
ConfigChangeContentBuilder builder = new ConfigChangeContentBuilder();
//校验对应的 Item 是否已经存在。若是,抛出异常
Item managedEntity = itemService.findOne(appId, clusterName, namespaceName, entity.getKey());
if (managedEntity != null) {
throw new BadRequestException("item already exists");
}
//保存Item对象
entity = itemService.save(entity);
//添加到 ConfigChangeContentBuilder
builder.createItem(entity);
//将 item 转换成 ItemDTO对象
dto = BeanUtils.transform(ItemDTO.class, entity);
//创建commit对象
Commit commit = new Commit();
commit.setAppId(appId);
commit.setClusterName(clusterName);
commit.setNamespaceName(namespaceName);
commit.setChangeSets(builder.build());
commit.setDataChangeCreatedBy(dto.getDataChangeLastModifiedBy());
commit.setDataChangeLastModifiedBy(dto.getDataChangeLastModifiedBy());
commitService.save(commit);
return dto;
}