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