Coverage Report - com.ctrip.framework.apollo.adminservice.aop.NamespaceLockAspect
 
Classes in this File Line Coverage Branch Coverage Complexity
NamespaceLockAspect
13%
6/44
10%
1/10
2.375
 
 1  
 package com.ctrip.framework.apollo.adminservice.aop;
 2  
 
 3  
 
 4  
 import com.ctrip.framework.apollo.biz.entity.Item;
 5  
 import com.ctrip.framework.apollo.biz.entity.Namespace;
 6  
 import com.ctrip.framework.apollo.biz.entity.NamespaceLock;
 7  
 import com.ctrip.framework.apollo.biz.service.ItemService;
 8  
 import com.ctrip.framework.apollo.biz.service.NamespaceLockService;
 9  
 import com.ctrip.framework.apollo.biz.service.NamespaceService;
 10  
 import com.ctrip.framework.apollo.biz.utils.ApolloSwitcher;
 11  
 import com.ctrip.framework.apollo.core.dto.ItemChangeSets;
 12  
 import com.ctrip.framework.apollo.core.dto.ItemDTO;
 13  
 import com.ctrip.framework.apollo.core.exception.BadRequestException;
 14  
 
 15  
 import org.aspectj.lang.annotation.Aspect;
 16  
 import org.aspectj.lang.annotation.Before;
 17  
 import org.slf4j.Logger;
 18  
 import org.slf4j.LoggerFactory;
 19  
 import org.springframework.beans.factory.annotation.Autowired;
 20  
 import org.springframework.dao.DataIntegrityViolationException;
 21  
 import org.springframework.stereotype.Component;
 22  
 
 23  
 
 24  
 /**
 25  
  * 一个namespace在一次发布中只能允许一个人修改配置
 26  
  * 通过数据库lock表来实现
 27  
  */
 28  
 @Aspect
 29  
 @Component
 30  1
 public class NamespaceLockAspect {
 31  1
   private static final Logger logger = LoggerFactory.getLogger(NamespaceLockAspect.class);
 32  
 
 33  
 
 34  
   @Autowired
 35  
   private NamespaceLockService namespaceLockService;
 36  
   @Autowired
 37  
   private NamespaceService namespaceService;
 38  
   @Autowired
 39  
   private ItemService itemService;
 40  
   @Autowired
 41  
   private ApolloSwitcher apolloSwitcher;
 42  
 
 43  
 
 44  
   @Before("@annotation(PreAcquireNamespaceLock) && args(appId, clusterName, namespaceName, item, ..)")
 45  
   public void requireLockAdvice(String appId, String clusterName, String namespaceName, ItemDTO item) {
 46  0
     acquireLock(appId, clusterName, namespaceName, item.getDataChangeLastModifiedBy());
 47  0
   }
 48  
 
 49  
   @Before("@annotation(PreAcquireNamespaceLock) && args(appId, clusterName, namespaceName, changeSet, ..)")
 50  
   public void requireLockAdvice(String appId, String clusterName, String namespaceName,
 51  
                                             ItemChangeSets changeSet) {
 52  5
     acquireLock(appId, clusterName, namespaceName, changeSet.getDataChangeLastModifiedBy());
 53  5
   }
 54  
 
 55  
   @Before("@annotation(PreAcquireNamespaceLock) && args(itemId, operator, ..)")
 56  
   public void requireLockAdvice(long itemId, String operator) {
 57  0
     Item item = itemService.findOne(itemId);
 58  
 
 59  0
     acquireLock(item.getNamespaceId(), operator);
 60  0
   }
 61  
 
 62  
   private void acquireLock(String appId, String clusterName, String namespaceName, String currentUser) {
 63  5
     if (apolloSwitcher.isNamespaceLockSwitchOff()) {
 64  5
       return;
 65  
     }
 66  
 
 67  0
     Namespace namespace = namespaceService.findOne(appId, clusterName, namespaceName);
 68  
 
 69  0
     acquireLock(namespace, currentUser);
 70  0
   }
 71  
 
 72  
   private void acquireLock(long namespaceId, String currentUser) {
 73  0
     Namespace namespace = namespaceService.findOne(namespaceId);
 74  
 
 75  0
     acquireLock(namespace, currentUser);
 76  
 
 77  0
   }
 78  
 
 79  
   private void acquireLock(Namespace namespace, String currentUser) {
 80  0
     if (namespace == null) {
 81  0
       throw new BadRequestException("namespace not exist.");
 82  
     }
 83  
 
 84  0
     long namespaceId = namespace.getId();
 85  
 
 86  0
     NamespaceLock namespaceLock = namespaceLockService.findLock(namespaceId);
 87  0
     if (namespaceLock == null) {
 88  
       try {
 89  0
         tryLock(namespaceId, currentUser);
 90  
         //lock success
 91  0
       } catch (DataIntegrityViolationException e) {
 92  
         //lock fail
 93  0
         acquireLockFail(namespace, currentUser);
 94  0
       } catch (Exception e){
 95  0
         logger.error("try lock error", e);
 96  0
         throw e;
 97  0
       }
 98  
     } else {
 99  
       //check lock owner is current user
 100  0
       String lockOwner = namespaceLock.getDataChangeCreatedBy();
 101  0
       if (!lockOwner.equals(currentUser)) {
 102  0
         acquireLockFail(namespace, currentUser);
 103  
       }
 104  
     }
 105  0
   }
 106  
 
 107  
   private void tryLock(long namespaceId, String user) {
 108  0
     NamespaceLock lock = new NamespaceLock();
 109  0
     lock.setNamespaceId(namespaceId);
 110  0
     lock.setDataChangeCreatedBy(user);
 111  0
     lock.setDataChangeLastModifiedBy(user);
 112  0
     namespaceLockService.tryLock(lock);
 113  0
   }
 114  
 
 115  
   private void acquireLockFail(Namespace namespace, String currentUser){
 116  0
     NamespaceLock namespaceLock = namespaceLockService.findLock(namespace.getId());
 117  0
     if (namespaceLock == null){
 118  0
       acquireLock(namespace, currentUser);
 119  
     }
 120  0
     String lockOwner = namespaceLock.getDataChangeCreatedBy();
 121  0
     throw new BadRequestException("namespace:" + namespace.getNamespaceName() + " is modifying by " + lockOwner);
 122  
   }
 123  
 
 124  
 
 125  
 
 126  
 }