黑马程序员技术交流社区

标题: 【上海校区】配置中心 Apollo 源码解析 —— Portal 批量变更... [打印本页]

作者: 不二晨    时间: 2018-10-30 09:12
标题: 【上海校区】配置中心 Apollo 源码解析 —— Portal 批量变更...
1. 概述
老艿艿:本系列假定胖友已经阅读过 《Apollo 官方 wiki 文档》
本文接 《Apollo 源码解析 —— Portal 创建 Item》 文章,分享 Item 的批量变更。
整体流程如下图:
老艿艿:因为 Portal 是管理后台,所以从代码实现上,和业务系统非常相像。也因此,本文会略显啰嗦。
2. ItemChangeSets
com.ctrip.framework.apollo.common.dto.ItemChangeSets ,Item 变更集合。代码如下:
public class ItemChangeSets extends BaseDTO {    /**     * 新增 Item 集合     */    private List<ItemDTO> createItems = new LinkedList<>();    /**     * 修改 Item 集合     */    private List<ItemDTO> updateItems = new LinkedList<>();    /**     * 删除 Item 集合     */    private List<ItemDTO> deleteItems = new LinkedList<>();    public void addCreateItem(ItemDTO item) {        createItems.add(item);    }    public void addUpdateItem(ItemDTO item) {        updateItems.add(item);    }    public void addDeleteItem(ItemDTO item) {        deleteItems.add(item);    }        public boolean isEmpty() {        return createItems.isEmpty() && updateItems.isEmpty() && deleteItems.isEmpty();    }        // ... 省略 setting / getting 方法}3. ConfigTextResolver
在 apollo-portal 项目中,com.ctrip.framework.apollo.portal.component.txtresolver.ConfigTextResolver ,配置文本解析器接口。代码如下:
public interface ConfigTextResolver {    /**     * 解析文本,创建 ItemChangeSets 对象     *     * @param namespaceId Namespace 编号     * @param configText 配置文本     * @param baseItems 已存在的 ItemDTO 们     * @return ItemChangeSets 对象     */    ItemChangeSets resolve(long namespaceId, String configText, List<ItemDTO> baseItems);}3.1 FileTextResolver
com.ctrip.framework.apollo.portal.component.txtresolver.FileTextResolver ,实现 ConfigTextResolver 接口,文件配置文本解析器,适用于 yaml、yml、json、xml 格式。代码如下:
1: @Override 2: public ItemChangeSets resolve(long namespaceId, String configText, List<ItemDTO> baseItems) { 3:     ItemChangeSets changeSets = new ItemChangeSets(); 4:     // 配置文本为空,不进行修改 5:     if (StringUtils.isEmpty(configText)) { 6:         return changeSets; 7:     } 8:     // 不存在已有配置,创建 ItemDTO 到 ItemChangeSets 新增项 9:     if (CollectionUtils.isEmpty(baseItems)) {10:         changeSets.addCreateItem(createItem(namespaceId, 0, configText));11:     // 已存在配置,创建 ItemDTO 到 ItemChangeSets 修改项12:     } else {13:         ItemDTO beforeItem = baseItems.get(0);14:         if (!configText.equals(beforeItem.getValue())) { //update15:             changeSets.addUpdateItem(createItem(namespaceId, beforeItem.getId(), configText));16:         }17:     }18:     return changeSets;19: }3.2 PropertyResolver
com.ctrip.framework.apollo.portal.component.txtresolver.PropertyResolver ,实现 ConfigTextResolver 接口,properties 配置解析器。代码如下:
1: private static final String KV_SEPARATOR = "="; 2: private static final String ITEM_SEPARATOR = "\n"; 3:  4: @Override 5: public ItemChangeSets resolve(long namespaceId, String configText, List<ItemDTO> baseItems) { 6:     // 创建 Item Map ,以 lineNum 为 键 7:     Map<Integer, ItemDTO> oldLineNumMapItem = BeanUtils.mapByKey("lineNum", baseItems); 8:     // 创建 Item Map ,以 key 为 键 9:     Map<String, ItemDTO> oldKeyMapItem = BeanUtils.mapByKey("key", baseItems);10:     oldKeyMapItem.remove(""); // remove comment and blank item map.11: 12:     // 按照拆分 Property 配置13:     String[] newItems = configText.split(ITEM_SEPARATOR);14:     // 校验是否存在重复配置 Key 。若是,抛出 BadRequestException 异常15:     if (isHasRepeatKey(newItems)) {16:         throw new BadRequestException("config text has repeat key please check.");17:     }18: 19:     // 创建 ItemChangeSets 对象,并解析配置文件到 ItemChangeSets 中。20:     ItemChangeSets changeSets = new ItemChangeSets();21:     Map<Integer, String> newLineNumMapItem = new HashMap<>();//use for delete blank and comment item22:     int lineCounter = 1;23:     for (String newItem : newItems) {24:         newItem = newItem.trim();25:         newLineNumMapItem.put(lineCounter, newItem);26:         // 使用行号,获得已存在的 ItemDTO27:         ItemDTO oldItemByLine = oldLineNumMapItem.get(lineCounter);28:         // comment item 注释 Item29:         if (isCommentItem(newItem)) {30:             handleCommentLine(namespaceId, oldItemByLine, newItem, lineCounter, changeSets);31:         // blank item 空白 Item32:         } else if (isBlankItem(newItem)) {33:             handleBlankLine(namespaceId, oldItemByLine, lineCounter, changeSets);34:         // normal item 普通 Item35:         } else {36:             handleNormalLine(namespaceId, oldKeyMapItem, newItem, lineCounter, changeSets);37:         }38:         // 行号计数 + 139:         lineCounter++;40:     }41:     // 删除注释和空行配置项42:     deleteCommentAndBlankItem(oldLineNumMapItem, newLineNumMapItem, changeSets);43:     // 删除普通配置项44:     deleteNormalKVItem(oldKeyMapItem, changeSets);45:     return changeSets;46: }

作者: 不二晨    时间: 2018-10-31 14:24

作者: 魔都黑马少年梦    时间: 2018-11-1 16:09





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2