##### Coverage Report - com.ctrip.apollo.portal.service.PortalConfigService

Classes in this File | Line Coverage | Branch Coverage | Complexity
PortalConfigService |
72% | 62/86
83% | 15/18
| 3.0;3

1 |  |
     package com.ctrip.apollo.portal.service;
2 |  |
3 |  |
4 |  |
     import org.slf4j.Logger;
5 |  |
     import org.slf4j.LoggerFactory;
6 |  |
     import org.springframework.beans.factory.annotation.Autowired;
7 |  |
     import org.springframework.stereotype.Service;
8 |  |
     import org.springframework.util.CollectionUtils;
9 |  |
     import org.springframework.web.client.HttpClientErrorException;
10 |  |
11 |  |
     import com.ctrip.apollo.common.utils.BeanUtils;
12 |  |
     import com.ctrip.apollo.core.enums.Env;
13 |  |
     import com.ctrip.apollo.core.dto.ItemChangeSets;
14 |  |
     import com.ctrip.apollo.core.dto.ItemDTO;
15 |  |
     import com.ctrip.apollo.core.dto.NamespaceDTO;
16 |  |
     import com.ctrip.apollo.core.dto.ReleaseDTO;
17 |  |
     import com.ctrip.apollo.core.exception.BadRequestException;
18 |  |
     import com.ctrip.apollo.core.exception.NotFoundException;
19 |  |
     import com.ctrip.apollo.core.exception.ServiceException;
20 |  |
     import com.ctrip.apollo.portal.api.AdminServiceAPI;
21 |  |
     import com.ctrip.apollo.portal.entity.ItemDiffs;
22 |  |
     import com.ctrip.apollo.portal.entity.NamespaceIdentifer;
23 |  |
     import com.ctrip.apollo.portal.entity.form.NamespaceTextModel;
24 |  |
     import com.ctrip.apollo.portal.entity.form.NamespaceReleaseModel;
25 |  |
     import com.ctrip.apollo.portal.service.txtresolver.ConfigTextResolver;
26 |  |
27 |  |
     import java.util.LinkedList;
28 |  |
     import java.util.List;
29 |  |
     import java.util.Map;
30 |  |
31 |  |
     @Service
32 | 4 |
     public class PortalConfigService {
33 |  |
34 | 4 |
       private Logger logger = LoggerFactory.getLogger(PortalConfigService.class);
35 |  |
36 |  |
       @Autowired
37 |  |
       private AdminServiceAPI.NamespaceAPI namespaceAPI;
38 |  |
       @Autowired
39 |  |
       private AdminServiceAPI.ItemAPI itemAPI;
40 |  |
       @Autowired
41 |  |
       private AdminServiceAPI.ReleaseAPI releaseAPI;
42 |  |
43 |  |
       @Autowired
44 |  |
       private ConfigTextResolver resolver;
45 |  |
46 |  |
47 |  |
       /**
48 |  |
        * parse config text and update config items
49 |  |
        *
50 |  |
        * @return parse result
51 |  |
        */
52 |  |
       public void updateConfigItemByText(NamespaceTextModel model) {
53 | 1 |
         String appId = model.getAppId();
54 | 1 |
         Env env = model.getEnv();
55 | 1 |
         String clusterName = model.getClusterName();
56 | 1 |
         String namespaceName = model.getNamespaceName();
57 | 1 |
         long namespaceId = model.getNamespaceId();
58 | 1 |
         String configText = model.getConfigText();
59 |  |
60 | 2 |
         ItemChangeSets changeSets = resolver.resolve(namespaceId, configText,
61 | 1 |
                                                      itemAPI.findItems(appId, env, clusterName, namespaceName));
62 | 1 |
         if (changeSets.isEmpty()) {
63 | 0 |
           return;
64 |  |
         }
65 |  |
         try {
66 | 1 |
           itemAPI.updateItems(appId, env, clusterName, namespaceName, changeSets);
67 | 0 |
         } catch (Exception e) {
68 | 0 |
           logger.error("itemAPI.updateItems error. appId{},env:{},clusterName:{},namespaceName:{}", appId, env, clusterName,
69 |  |
                        namespaceName);
70 | 0 |
           throw new ServiceException(e.getMessage());
71 | 1 |
         }
72 | 1 |
       }
73 |  |
74 |  |
       /**
75 |  |
        * createRelease config items
76 |  |
        */
77 |  |
       public ReleaseDTO createRelease(NamespaceReleaseModel model) {
78 | 0 |
         return releaseAPI.release(model.getAppId(), model.getEnv(), model.getClusterName(),
79 | 0 |
                                   model.getNamespaceName(), model.getReleaseBy(), model.getReleaseComment());
80 |  |
       }
81 |  |
82 |  |
       public List<ItemDTO> findItems(String appId, Env env, String clusterName, String namespaceName) {
83 | 0 |
         return itemAPI.findItems(appId, env, clusterName, namespaceName);
84 |  |
       }
85 |  |
86 |  |
       public void syncItems(List<NamespaceIdentifer> comparedNamespaces, List<ItemDTO> sourceItems){
87 | 0 |
         List<ItemDiffs> itemDiffs = compare(comparedNamespaces, sourceItems);
88 | 0 |
         for (ItemDiffs itemDiff: itemDiffs){
89 | 0 |
           NamespaceIdentifer namespaceIdentifer = itemDiff.getNamespace();
90 |  |
           try {
91 | 0 |
             itemAPI
92 | 0 |
                 .updateItems(namespaceIdentifer.getAppId(), namespaceIdentifer.getEnv(),
93 | 0 |
                              namespaceIdentifer.getClusterName(),
94 | 0 |
                              namespaceIdentifer.getNamespaceName(), itemDiff.getDiffs());
95 | 0 |
           } catch (HttpClientErrorException e) {
96 | 0 |
             logger.error("sync items error. namespace:{}", namespaceIdentifer);
97 | 0 |
             throw new ServiceException(String.format("sync item error. env:%s, clusterName:%s", namespaceIdentifer.getEnv(),
98 | 0 |
                                                      namespaceIdentifer.getClusterName()), e);
99 | 0 |
           }
100 | 0 |
         }
101 | 0 |
       }
102 |  |
103 |  |
       public List<ItemDiffs> compare(List<NamespaceIdentifer> comparedNamespaces, List<ItemDTO> sourceItems) {
104 |  |
105 | 2 |
         List<ItemDiffs> result = new LinkedList<>();
106 |  |
107 | 2 |
         for (NamespaceIdentifer namespace : comparedNamespaces) {
108 |  |
109 | 2 |
           ItemDiffs itemDiffs = new ItemDiffs(namespace);
110 | 2 |
           itemDiffs.setDiffs(parseChangeSets(namespace, sourceItems));
111 | 2 |
           result.add(itemDiffs);
112 | 2 |
         }
113 |  |
114 | 2 |
         return result;
115 |  |
       }
116 |  |
117 |  |
       private long getNamespaceId(NamespaceIdentifer namespaceIdentifer) {
118 | 2 |
         String appId = namespaceIdentifer.getAppId();
119 | 2 |
         String clusterName = namespaceIdentifer.getClusterName();
120 | 2 |
         String namespaceName = namespaceIdentifer.getNamespaceName();
121 | 2 |
         Env env = namespaceIdentifer.getEnv();
122 | 2 |
         NamespaceDTO namespaceDTO = null;
123 |  |
         try {
124 | 2 |
           namespaceDTO = namespaceAPI.loadNamespace(appId, env, clusterName, namespaceName);
125 | 0 |
         } catch (NotFoundException e) {
126 | 0 |
           logger.warn("namespace not exist. appId:{}, env:{}, clusterName:{}, namespaceName:{}", appId, env, clusterName,
127 |  |
                       namespaceName);
128 | 0 |
           throw new BadRequestException(String.format(
129 |  |
               "namespace not exist. appId:%s, env:%s, clusterName:%s, namespaceName:%s", appId, env, clusterName,
130 |  |
               namespaceName));
131 | 2 |
         }
132 | 2 |
         return namespaceDTO.getId();
133 |  |
       }
134 |  |
135 |  |
       private ItemChangeSets parseChangeSets(NamespaceIdentifer namespace, List<ItemDTO> sourceItems){
136 | 2 |
         ItemChangeSets changeSets = new ItemChangeSets();
137 |  |
         List<ItemDTO>
138 | 2 |
             targetItems =
139 | 4 |
             itemAPI.findItems(namespace.getAppId(), namespace.getEnv(),
140 | 2 |
                               namespace.getClusterName(), namespace.getNamespaceName());
141 |  |
142 | 2 |
         long namespaceId = getNamespaceId(namespace);
143 | 2 |
         if (CollectionUtils.isEmpty(targetItems)) {//all source items is added
144 | 1 |
           int lineNum = 1;
145 | 1 |
           for (ItemDTO sourceItem : sourceItems) {
146 | 1 |
             changeSets.addCreateItem(buildItem(namespaceId, lineNum++, sourceItem));
147 | 1 |
           }
148 | 1 |
         } else {
149 | 1 |
           Map<String, ItemDTO> keyMapItem = BeanUtils.mapByKey("key", targetItems);
150 |  |
           String key, sourceValue, sourceComment;
151 | 1 |
           ItemDTO targetItem = null;
152 | 1 |
           int maxLineNum = targetItems.size();//append to last
153 | 1 |
           for (ItemDTO sourceItem : sourceItems) {
154 | 4 |
             key = sourceItem.getKey();
155 | 4 |
             sourceValue = sourceItem.getValue();
156 | 4 |
             sourceComment = sourceItem.getComment();
157 | 4 |
             targetItem = keyMapItem.get(key);
158 |  |
159 | 4 |
             if (targetItem == null) {//added items
160 |  |
161 | 1 |
               changeSets.addCreateItem(buildItem(namespaceId, ++maxLineNum, sourceItem));
162 |  |
163 | 3 |
             } else if (!sourceValue.equals(targetItem.getValue()) || !sourceComment
164 | 2 |
                 .equals(targetItem.getComment())) {//modified items
165 | 2 |
               targetItem.setValue(sourceValue);
166 | 2 |
               targetItem.setComment(sourceComment);
167 | 2 |
               changeSets.addUpdateItem(targetItem);
168 |  |
             }
169 | 4 |
           }
170 |  |
         }
171 |  |
172 | 2 |
         return changeSets;
173 |  |
       }
174 |  |
175 |  |
       private ItemDTO buildItem(long namespaceId, int lineNum, ItemDTO sourceItem) {
176 | 2 |
         ItemDTO createdItem = new ItemDTO();
177 | 2 |
         BeanUtils.copyEntityProperties(sourceItem, createdItem);
178 | 2 |
         createdItem.setLineNum(lineNum++);
179 | 2 |
         createdItem.setNamespaceId(namespaceId);
180 | 2 |
         return createdItem;
181 |  |
       }
182 |  |
     }