Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
apollo
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
openSource
apollo
Commits
20b5b8e6
Commit
20b5b8e6
authored
Mar 07, 2017
by
Jason Song
Committed by
GitHub
Mar 07, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #557 from lepdou/lock
unlock namespace when is redo operation
parents
a002fa82
9e51608a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
268 additions
and
4 deletions
+268
-4
NamespaceAcquireLockAspect.java
...k/apollo/adminservice/aop/NamespaceAcquireLockAspect.java
+2
-2
NamespaceUnlockAspect.java
...mework/apollo/adminservice/aop/NamespaceUnlockAspect.java
+147
-0
AllTests.java
...ava/com/ctrip/framework/apollo/adminservice/AllTests.java
+3
-1
NamespaceLockTest.java
.../framework/apollo/adminservice/aop/NamespaceLockTest.java
+1
-1
NamespaceUnlockAspectTest.java
...rk/apollo/adminservice/aop/NamespaceUnlockAspectTest.java
+115
-0
No files found.
apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/aop/NamespaceLockAspect.java
→
apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/aop/Namespace
Acquire
LockAspect.java
View file @
20b5b8e6
...
...
@@ -28,8 +28,8 @@ import org.springframework.stereotype.Component;
*/
@Aspect
@Component
public
class
NamespaceLockAspect
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
NamespaceLockAspect
.
class
);
public
class
Namespace
Acquire
LockAspect
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
Namespace
Acquire
LockAspect
.
class
);
@Autowired
...
...
apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/aop/NamespaceUnlockAspect.java
0 → 100644
View file @
20b5b8e6
package
com
.
ctrip
.
framework
.
apollo
.
adminservice
.
aop
;
import
com.google.common.collect.Maps
;
import
com.google.gson.Gson
;
import
com.ctrip.framework.apollo.biz.config.BizConfig
;
import
com.ctrip.framework.apollo.biz.entity.Item
;
import
com.ctrip.framework.apollo.biz.entity.Namespace
;
import
com.ctrip.framework.apollo.biz.entity.Release
;
import
com.ctrip.framework.apollo.biz.service.ItemService
;
import
com.ctrip.framework.apollo.biz.service.NamespaceLockService
;
import
com.ctrip.framework.apollo.biz.service.NamespaceService
;
import
com.ctrip.framework.apollo.biz.service.ReleaseService
;
import
com.ctrip.framework.apollo.common.constants.GsonType
;
import
com.ctrip.framework.apollo.common.dto.ItemChangeSets
;
import
com.ctrip.framework.apollo.common.dto.ItemDTO
;
import
com.ctrip.framework.apollo.common.exception.BadRequestException
;
import
com.ctrip.framework.apollo.core.utils.StringUtils
;
import
org.aspectj.lang.annotation.After
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
/**
* unlock namespace if is redo operation.
* --------------------------------------------
* For example: If namespace has a item K1 = v1
* --------------------------------------------
* First operate: change k1 = v2 (lock namespace)
* Second operate: change k1 = v1 (unlock namespace)
*
*/
@Aspect
@Component
public
class
NamespaceUnlockAspect
{
private
Gson
gson
=
new
Gson
();
@Autowired
private
NamespaceLockService
namespaceLockService
;
@Autowired
private
NamespaceService
namespaceService
;
@Autowired
private
ItemService
itemService
;
@Autowired
private
ReleaseService
releaseService
;
@Autowired
private
BizConfig
bizConfig
;
//create item
@After
(
"@annotation(PreAcquireNamespaceLock) && args(appId, clusterName, namespaceName, item, ..)"
)
public
void
requireLockAdvice
(
String
appId
,
String
clusterName
,
String
namespaceName
,
ItemDTO
item
)
{
tryUnlock
(
namespaceService
.
findOne
(
appId
,
clusterName
,
namespaceName
));
}
//update item
@After
(
"@annotation(PreAcquireNamespaceLock) && args(appId, clusterName, namespaceName, itemId, item, ..)"
)
public
void
requireLockAdvice
(
String
appId
,
String
clusterName
,
String
namespaceName
,
long
itemId
,
ItemDTO
item
)
{
tryUnlock
(
namespaceService
.
findOne
(
appId
,
clusterName
,
namespaceName
));
}
//update by change set
@After
(
"@annotation(PreAcquireNamespaceLock) && args(appId, clusterName, namespaceName, changeSet, ..)"
)
public
void
requireLockAdvice
(
String
appId
,
String
clusterName
,
String
namespaceName
,
ItemChangeSets
changeSet
)
{
tryUnlock
(
namespaceService
.
findOne
(
appId
,
clusterName
,
namespaceName
));
}
//delete item
@After
(
"@annotation(PreAcquireNamespaceLock) && args(itemId, operator, ..)"
)
public
void
requireLockAdvice
(
long
itemId
,
String
operator
)
{
Item
item
=
itemService
.
findOne
(
itemId
);
if
(
item
==
null
)
{
throw
new
BadRequestException
(
"item not exist."
);
}
tryUnlock
(
namespaceService
.
findOne
(
item
.
getNamespaceId
()));
}
private
void
tryUnlock
(
Namespace
namespace
)
{
if
(
bizConfig
.
isNamespaceLockSwitchOff
())
{
return
;
}
if
(!
isModified
(
namespace
))
{
namespaceLockService
.
unlock
(
namespace
.
getId
());
}
}
boolean
isModified
(
Namespace
namespace
)
{
Release
release
=
releaseService
.
findLatestActiveRelease
(
namespace
);
List
<
Item
>
items
=
itemService
.
findItems
(
namespace
.
getId
());
if
(
release
==
null
)
{
return
hasNormalItems
(
items
);
}
Map
<
String
,
String
>
releasedConfiguration
=
gson
.
fromJson
(
release
.
getConfigurations
(),
GsonType
.
CONFIG
);
Map
<
String
,
String
>
configurationFromItems
=
Maps
.
newHashMap
();
for
(
Item
item
:
items
)
{
String
key
=
item
.
getKey
();
if
(
StringUtils
.
isBlank
(
key
))
{
continue
;
}
//added
if
(
releasedConfiguration
.
get
(
key
)
==
null
)
{
return
true
;
}
configurationFromItems
.
put
(
key
,
item
.
getValue
());
}
for
(
Map
.
Entry
<
String
,
String
>
entry
:
releasedConfiguration
.
entrySet
())
{
String
key
=
entry
.
getKey
();
String
value
=
entry
.
getValue
();
//deleted or modified
if
(!
Objects
.
equals
(
configurationFromItems
.
get
(
key
),
value
))
{
return
true
;
}
}
return
false
;
}
private
boolean
hasNormalItems
(
List
<
Item
>
items
)
{
for
(
Item
item
:
items
)
{
if
(!
StringUtils
.
isEmpty
(
item
.
getKey
()))
{
return
true
;
}
}
return
false
;
}
}
apollo-adminservice/src/test/java/com/ctrip/framework/apollo/adminservice/AllTests.java
View file @
20b5b8e6
package
com
.
ctrip
.
framework
.
apollo
.
adminservice
;
import
com.ctrip.framework.apollo.adminservice.aop.NamespaceLockTest
;
import
com.ctrip.framework.apollo.adminservice.aop.NamespaceUnlockAspectTest
;
import
com.ctrip.framework.apollo.adminservice.controller.AppControllerTest
;
import
com.ctrip.framework.apollo.adminservice.controller.AppNamespaceControllerTest
;
import
com.ctrip.framework.apollo.adminservice.controller.ControllerExceptionTest
;
...
...
@@ -17,7 +18,8 @@ import org.junit.runners.Suite.SuiteClasses;
@SuiteClasses
({
AppControllerTest
.
class
,
ReleaseControllerTest
.
class
,
ItemSetControllerTest
.
class
,
ControllerExceptionTest
.
class
,
ControllerIntegrationExceptionTest
.
class
,
NamespaceLockTest
.
class
,
InstanceConfigControllerTest
.
class
,
AppNamespaceControllerTest
.
class
NamespaceLockTest
.
class
,
InstanceConfigControllerTest
.
class
,
AppNamespaceControllerTest
.
class
,
NamespaceUnlockAspectTest
.
class
})
public
class
AllTests
{
...
...
apollo-adminservice/src/test/java/com/ctrip/framework/apollo/adminservice/aop/NamespaceLockTest.java
View file @
20b5b8e6
...
...
@@ -42,7 +42,7 @@ public class NamespaceLockTest {
@Mock
private
BizConfig
bizConfig
;
@InjectMocks
NamespaceLockAspect
namespaceLockAspect
;
Namespace
Acquire
LockAspect
namespaceLockAspect
;
@Test
public
void
acquireLockWithNotLockedAndSwitchON
()
{
...
...
apollo-adminservice/src/test/java/com/ctrip/framework/apollo/adminservice/aop/NamespaceUnlockAspectTest.java
0 → 100644
View file @
20b5b8e6
package
com
.
ctrip
.
framework
.
apollo
.
adminservice
.
aop
;
import
com.ctrip.framework.apollo.biz.entity.Item
;
import
com.ctrip.framework.apollo.biz.entity.Namespace
;
import
com.ctrip.framework.apollo.biz.entity.Release
;
import
com.ctrip.framework.apollo.biz.service.ItemService
;
import
com.ctrip.framework.apollo.biz.service.ReleaseService
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.InjectMocks
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
static
org
.
mockito
.
Mockito
.
when
;
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
NamespaceUnlockAspectTest
{
@Mock
private
ReleaseService
releaseService
;
@Mock
private
ItemService
itemService
;
@InjectMocks
private
NamespaceUnlockAspect
namespaceUnlockAspect
;
@Test
public
void
testNamespaceHasNoNormalItemsAndRelease
()
{
long
namespaceId
=
1
;
Namespace
namespace
=
createNamespace
(
namespaceId
);
when
(
releaseService
.
findLatestActiveRelease
(
namespace
)).
thenReturn
(
null
);
when
(
itemService
.
findItems
(
namespaceId
)).
thenReturn
(
Collections
.
singletonList
(
createItem
(
""
,
""
)));
boolean
isModified
=
namespaceUnlockAspect
.
isModified
(
namespace
);
Assert
.
assertFalse
(
isModified
);
}
@Test
public
void
testNamespaceAddItem
()
{
long
namespaceId
=
1
;
Namespace
namespace
=
createNamespace
(
namespaceId
);
Release
release
=
createRelease
(
"{\"k1\":\"v1\"}"
);
List
<
Item
>
items
=
Arrays
.
asList
(
createItem
(
"k1"
,
"v1"
),
createItem
(
"k2"
,
"v2"
));
when
(
releaseService
.
findLatestActiveRelease
(
namespace
)).
thenReturn
(
release
);
when
(
itemService
.
findItems
(
namespaceId
)).
thenReturn
(
items
);
boolean
isModified
=
namespaceUnlockAspect
.
isModified
(
namespace
);
Assert
.
assertTrue
(
isModified
);
}
@Test
public
void
testNamespaceModifyItem
()
{
long
namespaceId
=
1
;
Namespace
namespace
=
createNamespace
(
namespaceId
);
Release
release
=
createRelease
(
"{\"k1\":\"v1\"}"
);
List
<
Item
>
items
=
Arrays
.
asList
(
createItem
(
"k1"
,
"v2"
));
when
(
releaseService
.
findLatestActiveRelease
(
namespace
)).
thenReturn
(
release
);
when
(
itemService
.
findItems
(
namespaceId
)).
thenReturn
(
items
);
boolean
isModified
=
namespaceUnlockAspect
.
isModified
(
namespace
);
Assert
.
assertTrue
(
isModified
);
}
@Test
public
void
testNamespaceDeleteItem
()
{
long
namespaceId
=
1
;
Namespace
namespace
=
createNamespace
(
namespaceId
);
Release
release
=
createRelease
(
"{\"k1\":\"v1\"}"
);
List
<
Item
>
items
=
Arrays
.
asList
(
createItem
(
"k2"
,
"v2"
));
when
(
releaseService
.
findLatestActiveRelease
(
namespace
)).
thenReturn
(
release
);
when
(
itemService
.
findItems
(
namespaceId
)).
thenReturn
(
items
);
boolean
isModified
=
namespaceUnlockAspect
.
isModified
(
namespace
);
Assert
.
assertTrue
(
isModified
);
}
private
Namespace
createNamespace
(
long
namespaceId
)
{
Namespace
namespace
=
new
Namespace
();
namespace
.
setId
(
namespaceId
);
return
namespace
;
}
private
Item
createItem
(
String
key
,
String
value
)
{
Item
item
=
new
Item
();
item
.
setKey
(
key
);
item
.
setValue
(
value
);
return
item
;
}
private
Release
createRelease
(
String
configuration
)
{
Release
release
=
new
Release
();
release
.
setConfigurations
(
configuration
);
return
release
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment