Coverage Report - com.ctrip.framework.apollo.portal.service.NamespaceService
 
Classes in this File Line Coverage Branch Coverage Complexity
NamespaceService
63%
63/100
62%
20/32
3.667
 
 1  
 package com.ctrip.framework.apollo.portal.service;
 2  
 
 3  
 import com.google.gson.Gson;
 4  
 
 5  
 import com.ctrip.framework.apollo.common.entity.AppNamespace;
 6  
 import com.ctrip.framework.apollo.common.utils.BeanUtils;
 7  
 import com.ctrip.framework.apollo.common.utils.ExceptionUtils;
 8  
 import com.ctrip.framework.apollo.core.ConfigConsts;
 9  
 import com.ctrip.framework.apollo.core.dto.AppNamespaceDTO;
 10  
 import com.ctrip.framework.apollo.core.dto.ItemDTO;
 11  
 import com.ctrip.framework.apollo.core.dto.NamespaceDTO;
 12  
 import com.ctrip.framework.apollo.core.dto.ReleaseDTO;
 13  
 import com.ctrip.framework.apollo.core.enums.Env;
 14  
 import com.ctrip.framework.apollo.core.exception.BadRequestException;
 15  
 import com.ctrip.framework.apollo.core.exception.ServiceException;
 16  
 import com.ctrip.framework.apollo.core.utils.StringUtils;
 17  
 import com.ctrip.framework.apollo.portal.PortalSettings;
 18  
 import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
 19  
 import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
 20  
 import com.ctrip.framework.apollo.portal.entity.vo.NamespaceVO;
 21  
 import com.ctrip.framework.apollo.portal.repository.AppNamespaceRepository;
 22  
 
 23  
 import org.slf4j.Logger;
 24  
 import org.slf4j.LoggerFactory;
 25  
 import org.springframework.beans.factory.annotation.Autowired;
 26  
 import org.springframework.http.HttpStatus;
 27  
 import org.springframework.stereotype.Service;
 28  
 import org.springframework.transaction.annotation.Transactional;
 29  
 import org.springframework.web.client.HttpClientErrorException;
 30  
 import org.springframework.web.client.HttpStatusCodeException;
 31  
 
 32  
 import java.util.Collections;
 33  
 import java.util.HashMap;
 34  
 import java.util.LinkedList;
 35  
 import java.util.List;
 36  
 import java.util.Map;
 37  
 import java.util.Objects;
 38  
 
 39  
 @Service
 40  2
 public class NamespaceService {
 41  
 
 42  2
   private Logger logger = LoggerFactory.getLogger(NamespaceService.class);
 43  
 
 44  
   @Autowired
 45  
   private UserInfoHolder userInfoHolder;
 46  
   @Autowired
 47  
   private AdminServiceAPI.ItemAPI itemAPI;
 48  
   @Autowired
 49  
   private AdminServiceAPI.ReleaseAPI releaseAPI;
 50  
   @Autowired
 51  
   private AdminServiceAPI.NamespaceAPI namespaceAPI;
 52  
   @Autowired
 53  
   private PortalSettings portalSettings;
 54  
   @Autowired
 55  
   private AppNamespaceRepository appNamespaceRepository;
 56  
   @Autowired
 57  
   private RoleInitializationService roleInitializationService;
 58  
 
 59  2
   private Gson gson = new Gson();
 60  
 
 61  
 
 62  
   public List<AppNamespace> findPublicAppNamespaces() {
 63  0
     return appNamespaceRepository.findByNameNot(ConfigConsts.NAMESPACE_APPLICATION);
 64  
   }
 65  
 
 66  
   public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace) {
 67  0
     if (StringUtils.isEmpty(namespace.getDataChangeCreatedBy())) {
 68  0
       namespace.setDataChangeCreatedBy(userInfoHolder.getUser().getUserId());
 69  
     }
 70  0
     namespace.setDataChangeLastModifiedBy(userInfoHolder.getUser().getUserId());
 71  0
     NamespaceDTO createdNamespace = namespaceAPI.createNamespace(env, namespace);
 72  
 
 73  0
     roleInitializationService.initNamespaceRoles(namespace.getAppId(), namespace.getNamespaceName());
 74  0
     return createdNamespace;
 75  
   }
 76  
 
 77  
   @Transactional
 78  
   public void createDefaultAppNamespace(String appId) {
 79  0
     if (!isAppNamespaceNameUnique(appId, appId)) {
 80  0
       throw new ServiceException("appnamespace not unique");
 81  
     }
 82  0
     AppNamespace appNs = new AppNamespace();
 83  0
     appNs.setAppId(appId);
 84  0
     appNs.setName(ConfigConsts.NAMESPACE_APPLICATION);
 85  0
     appNs.setComment("default app namespace");
 86  
 
 87  0
     String userId = userInfoHolder.getUser().getUserId();
 88  0
     appNs.setDataChangeCreatedBy(userId);
 89  0
     appNs.setDataChangeLastModifiedBy(userId);
 90  0
     appNamespaceRepository.save(appNs);
 91  0
   }
 92  
 
 93  
   public boolean isAppNamespaceNameUnique(String appId, String namespaceName) {
 94  0
     Objects.requireNonNull(appId, "AppId must not be null");
 95  0
     Objects.requireNonNull(namespaceName, "Namespace must not be null");
 96  0
     return Objects.isNull(appNamespaceRepository.findByAppIdAndName(appId, namespaceName));
 97  
   }
 98  
 
 99  
   @Transactional
 100  
   public AppNamespace createAppNamespaceInLocal(AppNamespace appNamespace) {
 101  
     //not unique
 102  0
     if (appNamespaceRepository.findByName(appNamespace.getName()) != null){
 103  0
       throw new BadRequestException(appNamespace.getName() + "已存在");
 104  
     }
 105  0
     AppNamespace managedAppNamespace = appNamespaceRepository.findByAppIdAndName(appNamespace.getAppId(), appNamespace.getName());
 106  
     //update
 107  0
     if (managedAppNamespace != null){
 108  0
       BeanUtils.copyEntityProperties(appNamespace, managedAppNamespace);
 109  0
       return appNamespaceRepository.save(managedAppNamespace);
 110  
     }else {
 111  0
       return appNamespaceRepository.save(appNamespace);
 112  
     }
 113  
   }
 114  
 
 115  
   /**
 116  
    * load cluster all namespace info with items
 117  
    */
 118  
   public List<NamespaceVO> findNampspaces(String appId, Env env, String clusterName) {
 119  
 
 120  1
     List<NamespaceDTO> namespaces = namespaceAPI.findNamespaceByCluster(appId, env, clusterName);
 121  1
     if (namespaces == null || namespaces.size() == 0) {
 122  0
       return Collections.emptyList();
 123  
     }
 124  
 
 125  1
     List<NamespaceVO> namespaceVOs = new LinkedList<>();
 126  1
     for (NamespaceDTO namespace : namespaces) {
 127  
 
 128  2
       NamespaceVO namespaceVO = null;
 129  
       try {
 130  2
         namespaceVO = parseNamespace(appId, env, clusterName, namespace);
 131  2
         namespaceVOs.add(namespaceVO);
 132  0
       } catch (Exception e) {
 133  0
         logger.error("parse namespace error. app id:{}, env:{}, clusterName:{}, namespace:{}",
 134  0
                      appId, env, clusterName, namespace.getNamespaceName(), e);
 135  0
         throw e;
 136  2
       }
 137  2
     }
 138  
 
 139  1
     return namespaceVOs;
 140  
   }
 141  
 
 142  
   @SuppressWarnings("unchecked")
 143  
   private NamespaceVO parseNamespace(String appId, Env env, String clusterName, NamespaceDTO namespace) {
 144  2
     NamespaceVO namespaceVO = new NamespaceVO();
 145  2
     namespaceVO.setNamespace(namespace);
 146  
 
 147  2
     List<NamespaceVO.ItemVO> itemVos = new LinkedList<>();
 148  2
     namespaceVO.setItems(itemVos);
 149  
 
 150  2
     String namespaceName = namespace.getNamespaceName();
 151  
 
 152  
     //latest Release
 153  2
     ReleaseDTO release = null;
 154  2
     Map<String, String> releaseItems = new HashMap<>();
 155  
     try {
 156  2
       release = releaseAPI.loadLatestRelease(appId, env, clusterName, namespaceName);
 157  2
       releaseItems = gson.fromJson(release.getConfigurations(), Map.class);
 158  0
     } catch (HttpClientErrorException e) {
 159  0
       if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
 160  0
         logger.warn(ExceptionUtils.toString(e));
 161  
       } else {
 162  0
         throw e;
 163  
       }
 164  2
     }
 165  
 
 166  
     //not Release config items
 167  2
     List<ItemDTO> items = itemAPI.findItems(appId, env, clusterName, namespaceName);
 168  2
     int modifiedItemCnt = 0;
 169  2
     for (ItemDTO itemDTO : items) {
 170  
 
 171  4
       NamespaceVO.ItemVO itemVO = parseItemVO(itemDTO, releaseItems);
 172  
 
 173  4
       if (itemVO.isModified()) {
 174  2
         modifiedItemCnt++;
 175  
       }
 176  
 
 177  4
       itemVos.add(itemVO);
 178  4
     }
 179  
 
 180  
     //deleted items
 181  2
     List<NamespaceVO.ItemVO> deletedItems = countDeletedItemNum(items, releaseItems);
 182  2
     itemVos.addAll(deletedItems);
 183  2
     modifiedItemCnt += deletedItems.size();
 184  
 
 185  2
     namespaceVO.setItemModifiedCnt(modifiedItemCnt);
 186  
 
 187  2
     return namespaceVO;
 188  
   }
 189  
 
 190  
   private List<NamespaceVO.ItemVO> countDeletedItemNum(List<ItemDTO> newItems, Map<String, String> releaseItems) {
 191  2
     Map<String, ItemDTO> newItemMap = BeanUtils.mapByKey("key", newItems);
 192  
 
 193  2
     List<NamespaceVO.ItemVO> deletedItems = new LinkedList<>();
 194  2
     for (Map.Entry<String, String> entry : releaseItems.entrySet()) {
 195  4
       String key = entry.getKey();
 196  4
       if (newItemMap.get(key) == null) {
 197  2
         NamespaceVO.ItemVO deletedItem = new NamespaceVO.ItemVO();
 198  
 
 199  2
         ItemDTO deletedItemDto = new ItemDTO();
 200  2
         deletedItemDto.setKey(key);
 201  2
         String oldValue = entry.getValue();
 202  2
         deletedItem.setItem(deletedItemDto);
 203  
 
 204  2
         deletedItemDto.setValue(oldValue);
 205  2
         deletedItem.setModified(true);
 206  2
         deletedItem.setOldValue(oldValue);
 207  2
         deletedItem.setNewValue("");
 208  2
         deletedItems.add(deletedItem);
 209  
       }
 210  4
     }
 211  2
     return deletedItems;
 212  
   }
 213  
 
 214  
   private NamespaceVO.ItemVO parseItemVO(ItemDTO itemDTO, Map<String, String> releaseItems) {
 215  4
     String key = itemDTO.getKey();
 216  4
     NamespaceVO.ItemVO itemVO = new NamespaceVO.ItemVO();
 217  4
     itemVO.setItem(itemDTO);
 218  4
     String newValue = itemDTO.getValue();
 219  4
     String oldValue = releaseItems.get(key);
 220  
     //new item or modified
 221  4
     if (!StringUtils.isEmpty(key) && (oldValue == null || !newValue.equals(oldValue))) {
 222  2
       itemVO.setModified(true);
 223  2
       itemVO.setOldValue(oldValue == null ? "" : oldValue);
 224  2
       itemVO.setNewValue(newValue);
 225  
     }
 226  4
     return itemVO;
 227  
   }
 228  
 
 229  
 }