##### Coverage Report - com.ctrip.framework.apollo.portal.service.PortalNamespaceService

Classes in this File | Line Coverage | Branch Coverage | Complexity
PortalNamespaceService |
70% | 63/89
66% | 20/30
| 4.142857142857143;4.143

1 |  |
     package com.ctrip.framework.apollo.portal.service;
2 |  |
3 |  |
     import com.google.gson.Gson;
4 |  |
5 |  |
     import com.ctrip.framework.apollo.common.utils.BeanUtils;
6 |  |
     import com.ctrip.framework.apollo.common.utils.ExceptionUtils;
7 |  |
     import com.ctrip.framework.apollo.core.dto.AppNamespaceDTO;
8 |  |
     import com.ctrip.framework.apollo.core.dto.ItemDTO;
9 |  |
     import com.ctrip.framework.apollo.core.dto.NamespaceDTO;
10 |  |
     import com.ctrip.framework.apollo.core.dto.ReleaseDTO;
11 |  |
     import com.ctrip.framework.apollo.core.enums.Env;
12 |  |
     import com.ctrip.framework.apollo.core.utils.StringUtils;
13 |  |
     import com.ctrip.framework.apollo.portal.PortalSettings;
14 |  |
     import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
15 |  |
     import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
16 |  |
     import com.ctrip.framework.apollo.portal.entity.vo.NamespaceVO;
17 |  |
18 |  |
     import org.slf4j.Logger;
19 |  |
     import org.slf4j.LoggerFactory;
20 |  |
     import org.springframework.beans.factory.annotation.Autowired;
21 |  |
     import org.springframework.http.HttpStatus;
22 |  |
     import org.springframework.stereotype.Service;
23 |  |
     import org.springframework.web.client.HttpClientErrorException;
24 |  |
     import org.springframework.web.client.HttpStatusCodeException;
25 |  |
26 |  |
     import java.util.Collections;
27 |  |
     import java.util.HashMap;
28 |  |
     import java.util.LinkedList;
29 |  |
     import java.util.List;
30 |  |
     import java.util.Map;
31 |  |
32 |  |
     @Service
33 | 2 |
     public class PortalNamespaceService {
34 |  |
35 | 2 |
       private Logger logger = LoggerFactory.getLogger(PortalNamespaceService.class);
36 |  |
37 |  |
       @Autowired
38 |  |
       private UserInfoHolder userInfoHolder;
39 |  |
       @Autowired
40 |  |
       private AdminServiceAPI.ItemAPI itemAPI;
41 |  |
       @Autowired
42 |  |
       private AdminServiceAPI.ReleaseAPI releaseAPI;
43 |  |
       @Autowired
44 |  |
       private AdminServiceAPI.NamespaceAPI namespaceAPI;
45 |  |
       @Autowired
46 |  |
       private PortalSettings portalSettings;
47 |  |
48 | 2 |
       private Gson gson = new Gson();
49 |  |
50 |  |
51 |  |
       public List<AppNamespaceDTO> findPublicAppNamespaces() {
52 | 0 |
         return namespaceAPI.findPublicAppNamespaces(portalSettings.getFirstAliveEnv());
53 |  |
       }
54 |  |
55 |  |
       public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace) {
56 | 0 |
         if (StringUtils.isEmpty(namespace.getDataChangeCreatedBy())){
57 | 0 |
           namespace.setDataChangeCreatedBy(userInfoHolder.getUser().getUserId());
58 |  |
         }
59 | 0 |
         namespace.setDataChangeLastModifiedBy(userInfoHolder.getUser().getUserId());
60 | 0 |
         return namespaceAPI.createNamespace(env, namespace);
61 |  |
       }
62 |  |
63 |  |
       public void createAppNamespace(AppNamespaceDTO appNamespace) {
64 | 0 |
         String operator = userInfoHolder.getUser().getUserId();
65 | 0 |
         if (StringUtils.isEmpty(appNamespace.getDataChangeCreatedBy())){
66 | 0 |
           appNamespace.setDataChangeCreatedBy(operator);
67 |  |
         }
68 | 0 |
         appNamespace.setDataChangeLastModifiedBy(operator);
69 | 0 |
         for (Env env : portalSettings.getActiveEnvs()) {
70 |  |
           try {
71 | 0 |
             namespaceAPI.createOrUpdate(env, appNamespace);
72 | 0 |
           } catch (HttpStatusCodeException e) {
73 | 0 |
             logger.error(ExceptionUtils.toString(e));
74 | 0 |
             throw e;
75 | 0 |
           }
76 | 0 |
         }
77 | 0 |
       }
78 |  |
79 |  |
       /**
80 |  |
        * load cluster all namespace info with items
81 |  |
        */
82 |  |
       public List<NamespaceVO> findNampspaces(String appId, Env env, String clusterName) {
83 |  |
84 | 1 |
         List<NamespaceDTO> namespaces = namespaceAPI.findNamespaceByCluster(appId, env, clusterName);
85 | 1 |
         if (namespaces == null || namespaces.size() == 0) {
86 | 0 |
           return Collections.emptyList();
87 |  |
         }
88 |  |
89 | 1 |
         List<NamespaceVO> namespaceVOs = new LinkedList<>();
90 | 1 |
         for (NamespaceDTO namespace : namespaces) {
91 |  |
92 | 2 |
           NamespaceVO namespaceVO = null;
93 |  |
           try {
94 | 2 |
             namespaceVO = parseNamespace(appId, env, clusterName, namespace);
95 | 2 |
             namespaceVOs.add(namespaceVO);
96 | 0 |
           } catch (Exception e) {
97 | 0 |
             logger.error("parse namespace error. app id:{}, env:{}, clusterName:{}, namespace:{}",
98 | 0 |
                          appId, env, clusterName, namespace.getNamespaceName(), e);
99 | 0 |
             throw e;
100 | 2 |
           }
101 | 2 |
         }
102 |  |
103 | 1 |
         return namespaceVOs;
104 |  |
       }
105 |  |
106 |  |
       @SuppressWarnings("unchecked")
107 |  |
       private NamespaceVO parseNamespace(String appId, Env env, String clusterName, NamespaceDTO namespace) {
108 | 2 |
         NamespaceVO namespaceVO = new NamespaceVO();
109 | 2 |
         namespaceVO.setNamespace(namespace);
110 |  |
111 | 2 |
         List<NamespaceVO.ItemVO> itemVos = new LinkedList<>();
112 | 2 |
         namespaceVO.setItems(itemVos);
113 |  |
114 | 2 |
         String namespaceName = namespace.getNamespaceName();
115 |  |
116 |  |
         //latest Release
117 | 2 |
         ReleaseDTO release = null;
118 | 2 |
         Map<String, String> releaseItems = new HashMap<>();
119 |  |
         try {
120 | 2 |
           release = releaseAPI.loadLatestRelease(appId, env, clusterName, namespaceName);
121 | 2 |
           releaseItems = gson.fromJson(release.getConfigurations(), Map.class);
122 | 0 |
         } catch (HttpClientErrorException e) {
123 | 0 |
           if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
124 | 0 |
             logger.warn(ExceptionUtils.toString(e));
125 |  |
           } else {
126 | 0 |
             throw e;
127 |  |
           }
128 | 2 |
         }
129 |  |
130 |  |
         //not Release config items
131 | 2 |
         List<ItemDTO> items = itemAPI.findItems(appId, env, clusterName, namespaceName);
132 | 2 |
         int modifiedItemCnt = 0;
133 | 2 |
         for (ItemDTO itemDTO : items) {
134 |  |
135 | 4 |
           NamespaceVO.ItemVO itemVO = parseItemVO(itemDTO, releaseItems);
136 |  |
137 | 4 |
           if (itemVO.isModified()) {
138 | 2 |
             modifiedItemCnt++;
139 |  |
           }
140 |  |
141 | 4 |
           itemVos.add(itemVO);
142 | 4 |
         }
143 |  |
144 |  |
         //deleted items
145 | 2 |
         List<NamespaceVO.ItemVO> deletedItems = countDeletedItemNum(items, releaseItems);
146 | 2 |
         itemVos.addAll(deletedItems);
147 | 2 |
         modifiedItemCnt += deletedItems.size();
148 |  |
149 | 2 |
         namespaceVO.setItemModifiedCnt(modifiedItemCnt);
150 |  |
151 | 2 |
         return namespaceVO;
152 |  |
       }
153 |  |
154 |  |
       private List<NamespaceVO.ItemVO> countDeletedItemNum(List<ItemDTO> newItems, Map<String, String> releaseItems) {
155 | 2 |
         Map<String, ItemDTO> newItemMap = BeanUtils.mapByKey("key", newItems);
156 |  |
157 | 2 |
         List<NamespaceVO.ItemVO> deletedItems = new LinkedList<>();
158 | 2 |
         for (Map.Entry<String, String> entry: releaseItems.entrySet()){
159 | 4 |
           String key = entry.getKey();
160 | 4 |
           if (newItemMap.get(key) == null){
161 | 2 |
             NamespaceVO.ItemVO deletedItem = new NamespaceVO.ItemVO();
162 |  |
163 | 2 |
             ItemDTO deletedItemDto = new ItemDTO();
164 | 2 |
             deletedItemDto.setKey(key);
165 | 2 |
             String oldValue = entry.getValue();
166 | 2 |
             deletedItem.setItem(deletedItemDto);
167 |  |
168 | 2 |
             deletedItemDto.setValue(oldValue);
169 | 2 |
             deletedItem.setModified(true);
170 | 2 |
             deletedItem.setOldValue(oldValue);
171 | 2 |
             deletedItem.setNewValue("");
172 | 2 |
             deletedItems.add(deletedItem);
173 |  |
           }
174 | 4 |
         }
175 | 2 |
         return deletedItems;
176 |  |
       }
177 |  |
178 |  |
       private NamespaceVO.ItemVO parseItemVO(ItemDTO itemDTO, Map<String, String> releaseItems) {
179 | 4 |
         String key = itemDTO.getKey();
180 | 4 |
         NamespaceVO.ItemVO itemVO = new NamespaceVO.ItemVO();
181 | 4 |
         itemVO.setItem(itemDTO);
182 | 4 |
         String newValue = itemDTO.getValue();
183 | 4 |
         String oldValue = releaseItems.get(key);
184 |  |
         //new item or modified
185 | 4 |
         if (!StringUtils.isEmpty(key) && (oldValue == null || !newValue.equals(oldValue))) {
186 | 2 |
           itemVO.setModified(true);
187 | 2 |
           itemVO.setOldValue(oldValue == null ? "" : oldValue);
188 | 2 |
           itemVO.setNewValue(newValue);
189 |  |
         }
190 | 4 |
         return itemVO;
191 |  |
       }
192 |  |
193 |  |
     }