Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
apollo
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
Administrator
apollo
Commits
a684730f
Commit
a684730f
authored
Feb 09, 2017
by
lepdou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
delete namespace
parent
202363b5
Changes
39
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
962 additions
and
225 deletions
+962
-225
apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AppNamespaceController.java
...pollo/adminservice/controller/AppNamespaceController.java
+22
-0
apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/NamespaceRepository.java
.../framework/apollo/biz/repository/NamespaceRepository.java
+7
-0
apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppNamespaceService.java
...rip/framework/apollo/biz/service/AppNamespaceService.java
+9
-6
apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java
.../ctrip/framework/apollo/biz/service/NamespaceService.java
+41
-0
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AllTests.java
...rc/test/java/com/ctrip/framework/apollo/biz/AllTests.java
+4
-2
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/MockBeanFactory.java
.../java/com/ctrip/framework/apollo/biz/MockBeanFactory.java
+54
-0
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/BizDBPropertySourceTest.java
...framework/apollo/biz/service/BizDBPropertySourceTest.java
+7
-15
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/NamespaceServiceIntegrationTest.java
...k/apollo/biz/service/NamespaceServiceIntegrationTest.java
+91
-0
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/NamespaceServiceTest.java
...ip/framework/apollo/biz/service/NamespaceServiceTest.java
+56
-71
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/ReleaseServiceTest.java
...trip/framework/apollo/biz/service/ReleaseServiceTest.java
+3
-16
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/utils/ReleaseKeyGeneratorTest.java
...p/framework/apollo/biz/utils/ReleaseKeyGeneratorTest.java
+3
-9
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java
...om/ctrip/framework/apollo/portal/api/AdminServiceAPI.java
+24
-4
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java
...ramework/apollo/portal/component/PermissionValidator.java
+3
-1
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java
...amework/apollo/portal/controller/NamespaceController.java
+15
-2
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/NamespaceBranchService.java
...amework/apollo/portal/service/NamespaceBranchService.java
+0
-3
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/NamespaceService.java
...rip/framework/apollo/portal/service/NamespaceService.java
+44
-9
apollo-portal/src/main/resources/static/config.html
apollo-portal/src/main/resources/static/config.html
+28
-0
apollo-portal/src/main/resources/static/img/delete.png
apollo-portal/src/main/resources/static/img/delete.png
+0
-0
apollo-portal/src/main/resources/static/img/operate.png
apollo-portal/src/main/resources/static/img/operate.png
+0
-0
apollo-portal/src/main/resources/static/img/rollback.png
apollo-portal/src/main/resources/static/img/rollback.png
+0
-0
apollo-portal/src/main/resources/static/img/time.png
apollo-portal/src/main/resources/static/img/time.png
+0
-0
apollo-portal/src/main/resources/static/img/title.png
apollo-portal/src/main/resources/static/img/title.png
+0
-0
apollo-portal/src/main/resources/static/img/user.png
apollo-portal/src/main/resources/static/img/user.png
+0
-0
apollo-portal/src/main/resources/static/scripts/controller/config/ConfigNamespaceController.js
...ic/scripts/controller/config/ConfigNamespaceController.js
+30
-0
apollo-portal/src/main/resources/static/scripts/directive/delete-namespace-modal-directive.js
...tic/scripts/directive/delete-namespace-modal-directive.js
+182
-0
apollo-portal/src/main/resources/static/scripts/directive/directive.js
.../src/main/resources/static/scripts/directive/directive.js
+13
-2
apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js
...ces/static/scripts/directive/namespace-panel-directive.js
+12
-3
apollo-portal/src/main/resources/static/scripts/services/EventManager.js
...rc/main/resources/static/scripts/services/EventManager.js
+4
-1
apollo-portal/src/main/resources/static/scripts/services/NamespaceService.js
...ain/resources/static/scripts/services/NamespaceService.js
+48
-2
apollo-portal/src/main/resources/static/scripts/services/UserService.js
...src/main/resources/static/scripts/services/UserService.js
+18
-14
apollo-portal/src/main/resources/static/styles/common-style.css
...-portal/src/main/resources/static/styles/common-style.css
+4
-0
apollo-portal/src/main/resources/static/views/component/confirm-dialog.html
...main/resources/static/views/component/confirm-dialog.html
+2
-3
apollo-portal/src/main/resources/static/views/component/delete-namespace-modal.html
...ources/static/views/component/delete-namespace-modal.html
+25
-0
apollo-portal/src/main/resources/static/views/component/namespace-panel-branch-tab.html
...es/static/views/component/namespace-panel-branch-tab.html
+1
-1
apollo-portal/src/main/resources/static/views/component/namespace-panel-header.html
...ources/static/views/component/namespace-panel-header.html
+2
-2
apollo-portal/src/main/resources/static/views/component/namespace-panel-master-tab.html
...es/static/views/component/namespace-panel-master-tab.html
+43
-18
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/ConfigServiceTest.java
...ip/framework/apollo/portal/service/ConfigServiceTest.java
+23
-20
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/NamespaceServiceTest.java
...framework/apollo/portal/service/NamespaceServiceTest.java
+142
-20
scripts/sql/apolloconfigdb.sql
scripts/sql/apolloconfigdb.sql
+2
-1
No files found.
apollo-adminservice/src/main/java/com/ctrip/framework/apollo/adminservice/controller/AppNamespaceController.java
View file @
a684730f
package
com
.
ctrip
.
framework
.
apollo
.
adminservice
.
controller
;
import
com.ctrip.framework.apollo.biz.entity.Namespace
;
import
com.ctrip.framework.apollo.biz.service.AppNamespaceService
;
import
com.ctrip.framework.apollo.biz.service.NamespaceService
;
import
com.ctrip.framework.apollo.common.dto.AppNamespaceDTO
;
import
com.ctrip.framework.apollo.common.dto.NamespaceDTO
;
import
com.ctrip.framework.apollo.common.entity.AppNamespace
;
import
com.ctrip.framework.apollo.common.exception.BadRequestException
;
import
com.ctrip.framework.apollo.common.utils.BeanUtils
;
...
...
@@ -9,16 +12,22 @@ import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import
com.ctrip.framework.apollo.core.utils.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
@RestController
public
class
AppNamespaceController
{
@Autowired
private
AppNamespaceService
appNamespaceService
;
@Autowired
private
NamespaceService
namespaceService
;
@RequestMapping
(
value
=
"/apps/{appId}/appnamespaces"
,
method
=
RequestMethod
.
POST
)
public
AppNamespaceDTO
create
(
@RequestBody
AppNamespaceDTO
appNamespace
)
{
...
...
@@ -40,4 +49,17 @@ public class AppNamespaceController {
}
@RequestMapping
(
value
=
"/appnamespaces/{publicNamespaceName}/namespaces"
,
method
=
RequestMethod
.
GET
)
public
List
<
NamespaceDTO
>
findPublicAppNamespaceAllNamespaces
(
@PathVariable
String
publicNamespaceName
,
Pageable
pageable
)
{
List
<
Namespace
>
namespaces
=
namespaceService
.
findPublicAppNamespaceAllNamespaces
(
publicNamespaceName
,
pageable
);
return
BeanUtils
.
batchTransform
(
NamespaceDTO
.
class
,
namespaces
);
}
@RequestMapping
(
value
=
"/appnamespaces/{publicNamespaceName}/associated-namespaces/count"
,
method
=
RequestMethod
.
GET
)
public
int
countPublicAppNamespaceAssociatedNamespaces
(
@PathVariable
String
publicNamespaceName
)
{
return
namespaceService
.
countPublicAppNamespaceAssociatedNamespaces
(
publicNamespaceName
);
}
}
apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/NamespaceRepository.java
View file @
a684730f
...
...
@@ -2,6 +2,8 @@ package com.ctrip.framework.apollo.biz.repository;
import
com.ctrip.framework.apollo.biz.entity.Namespace
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.jpa.repository.Modifying
;
import
org.springframework.data.jpa.repository.Query
;
import
org.springframework.data.repository.PagingAndSortingRepository
;
...
...
@@ -19,4 +21,9 @@ public interface NamespaceRepository extends PagingAndSortingRepository<Namespac
int
batchDelete
(
String
appId
,
String
clusterName
,
String
operator
);
List
<
Namespace
>
findByAppIdAndNamespaceName
(
String
appId
,
String
namespaceName
);
List
<
Namespace
>
findByNamespaceName
(
String
namespaceName
,
Pageable
page
);
int
countByNamespaceNameAndAppIdNot
(
String
namespaceName
,
String
appId
);
}
apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppNamespaceService.java
View file @
a684730f
...
...
@@ -8,6 +8,7 @@ import com.ctrip.framework.apollo.biz.entity.Cluster;
import
com.ctrip.framework.apollo.biz.entity.Namespace
;
import
com.ctrip.framework.apollo.biz.repository.AppNamespaceRepository
;
import
com.ctrip.framework.apollo.common.entity.AppNamespace
;
import
com.ctrip.framework.apollo.common.exception.BadRequestException
;
import
com.ctrip.framework.apollo.common.exception.ServiceException
;
import
com.ctrip.framework.apollo.common.utils.BeanUtils
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
...
...
@@ -54,12 +55,13 @@ public class AppNamespaceService {
return
appNamespaceRepository
.
findByNameInAndIsPublicTrue
(
namespaceNames
);
}
public
List
<
AppNamespace
>
findPrivateAppNamespace
(
String
appId
){
public
List
<
AppNamespace
>
findPrivateAppNamespace
(
String
appId
)
{
return
appNamespaceRepository
.
findByAppIdAndIsPublic
(
appId
,
false
);
}
public
AppNamespace
findOne
(
String
appId
,
String
namespaceName
){
Preconditions
.
checkArgument
(!
StringUtils
.
isContainEmpty
(
appId
,
namespaceName
),
"appId or Namespace must not be null"
);
public
AppNamespace
findOne
(
String
appId
,
String
namespaceName
)
{
Preconditions
.
checkArgument
(!
StringUtils
.
isContainEmpty
(
appId
,
namespaceName
),
"appId or Namespace must not be null"
);
return
appNamespaceRepository
.
findByAppIdAndName
(
appId
,
namespaceName
);
}
...
...
@@ -90,7 +92,7 @@ public class AppNamespaceService {
}
@Transactional
public
AppNamespace
createAppNamespace
(
AppNamespace
appNamespace
){
public
AppNamespace
createAppNamespace
(
AppNamespace
appNamespace
)
{
String
createBy
=
appNamespace
.
getDataChangeCreatedBy
();
if
(!
isAppNamespaceNameUnique
(
appNamespace
.
getAppId
(),
appNamespace
.
getName
()))
{
throw
new
ServiceException
(
"appnamespace not unique"
);
...
...
@@ -109,12 +111,13 @@ public class AppNamespaceService {
return
appNamespace
;
}
public
AppNamespace
update
(
AppNamespace
appNamespace
){
public
AppNamespace
update
(
AppNamespace
appNamespace
)
{
AppNamespace
managedNs
=
appNamespaceRepository
.
findByAppIdAndName
(
appNamespace
.
getAppId
(),
appNamespace
.
getName
());
BeanUtils
.
copyEntityProperties
(
appNamespace
,
managedNs
);
managedNs
=
appNamespaceRepository
.
save
(
managedNs
);
auditService
.
audit
(
AppNamespace
.
class
.
getSimpleName
(),
managedNs
.
getId
(),
Audit
.
OP
.
UPDATE
,
managedNs
.
getDataChangeLastModifiedBy
());
auditService
.
audit
(
AppNamespace
.
class
.
getSimpleName
(),
managedNs
.
getId
(),
Audit
.
OP
.
UPDATE
,
managedNs
.
getDataChangeLastModifiedBy
());
return
managedNs
;
}
...
...
apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java
View file @
a684730f
...
...
@@ -18,12 +18,14 @@ import com.ctrip.framework.apollo.common.utils.BeanUtils;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.util.CollectionUtils
;
import
java.util.Collections
;
import
java.util.Date
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
...
...
@@ -117,7 +119,46 @@ public class NamespaceService {
//and default cluster's namespace exist but never published.
//return custom cluster's namespace
return
namespace
;
}
public
List
<
Namespace
>
findPublicAppNamespaceAllNamespaces
(
String
namespaceName
,
Pageable
page
)
{
AppNamespace
publicAppNamespace
=
appNamespaceService
.
findPublicNamespaceByName
(
namespaceName
);
if
(
publicAppNamespace
==
null
)
{
throw
new
BadRequestException
(
String
.
format
(
"Public appNamespace not exists. NamespaceName = %s"
,
namespaceName
));
}
List
<
Namespace
>
namespaces
=
namespaceRepository
.
findByNamespaceName
(
namespaceName
,
page
);
return
filterChildNamespace
(
namespaces
);
}
private
List
<
Namespace
>
filterChildNamespace
(
List
<
Namespace
>
namespaces
)
{
List
<
Namespace
>
result
=
new
LinkedList
<>();
if
(
CollectionUtils
.
isEmpty
(
namespaces
))
{
return
result
;
}
for
(
Namespace
namespace
:
namespaces
)
{
if
(!
isChildNamespace
(
namespace
))
{
result
.
add
(
namespace
);
}
}
return
result
;
}
public
int
countPublicAppNamespaceAssociatedNamespaces
(
String
publicNamespaceName
)
{
AppNamespace
publicAppNamespace
=
appNamespaceService
.
findPublicNamespaceByName
(
publicNamespaceName
);
if
(
publicAppNamespace
==
null
)
{
throw
new
BadRequestException
(
String
.
format
(
"Public appNamespace not exists. NamespaceName = %s"
,
publicNamespaceName
));
}
return
namespaceRepository
.
countByNamespaceNameAndAppIdNot
(
publicNamespaceName
,
publicAppNamespace
.
getAppId
());
}
public
List
<
Namespace
>
findNamespaces
(
String
appId
,
String
clusterName
)
{
...
...
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AllTests.java
View file @
a684730f
...
...
@@ -12,6 +12,7 @@ import com.ctrip.framework.apollo.biz.service.ClusterServiceTest;
import
com.ctrip.framework.apollo.biz.service.InstanceServiceTest
;
import
com.ctrip.framework.apollo.biz.service.NamespaceBranchServiceTest
;
import
com.ctrip.framework.apollo.biz.service.NamespacePublishInfoTest
;
import
com.ctrip.framework.apollo.biz.service.NamespaceServiceIntegrationTest
;
import
com.ctrip.framework.apollo.biz.service.NamespaceServiceTest
;
import
com.ctrip.framework.apollo.biz.service.ReleaseCreationTest
;
import
com.ctrip.framework.apollo.biz.service.ReleaseServiceTest
;
...
...
@@ -39,8 +40,9 @@ import org.junit.runners.Suite.SuiteClasses;
NamespaceBranchServiceTest
.
class
,
ReleaseCreationTest
.
class
,
NamespacePublishInfoTest
.
class
,
NamespaceServiceTest
.
class
,
BizConfigTest
.
class
NamespaceServiceIntegrationTest
.
class
,
BizConfigTest
.
class
,
NamespaceServiceTest
.
class
})
public
class
AllTests
{
...
...
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/MockBeanFactory.java
0 → 100644
View file @
a684730f
package
com
.
ctrip
.
framework
.
apollo
.
biz
;
import
com.ctrip.framework.apollo.biz.entity.Namespace
;
import
com.ctrip.framework.apollo.biz.entity.Release
;
import
com.ctrip.framework.apollo.biz.entity.ServerConfig
;
import
com.ctrip.framework.apollo.common.entity.AppNamespace
;
public
class
MockBeanFactory
{
public
static
Namespace
mockNamespace
(
String
appId
,
String
clusterName
,
String
namespaceName
)
{
Namespace
instance
=
new
Namespace
();
instance
.
setAppId
(
appId
);
instance
.
setClusterName
(
clusterName
);
instance
.
setNamespaceName
(
namespaceName
);
return
instance
;
}
public
static
AppNamespace
mockAppNamespace
(
String
appId
,
String
name
,
boolean
isPublic
)
{
AppNamespace
instance
=
new
AppNamespace
();
instance
.
setAppId
(
appId
);
instance
.
setName
(
name
);
instance
.
setPublic
(
isPublic
);
return
instance
;
}
public
static
ServerConfig
mockServerConfig
(
String
key
,
String
value
,
String
cluster
)
{
ServerConfig
instance
=
new
ServerConfig
();
instance
.
setKey
(
key
);
instance
.
setValue
(
value
);
instance
.
setCluster
(
cluster
);
return
instance
;
}
public
static
Release
mockRelease
(
long
releaseId
,
String
releaseKey
,
String
appId
,
String
clusterName
,
String
groupName
,
String
configurations
)
{
Release
instance
=
new
Release
();
instance
.
setId
(
releaseId
);
instance
.
setReleaseKey
(
releaseKey
);
instance
.
setAppId
(
appId
);
instance
.
setClusterName
(
clusterName
);
instance
.
setNamespaceName
(
groupName
);
instance
.
setConfigurations
(
configurations
);
return
instance
;
}
}
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/BizDBPropertySourceTest.java
View file @
a684730f
...
...
@@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.biz.service;
import
com.google.common.collect.Lists
;
import
com.ctrip.framework.apollo.biz.AbstractUnitTest
;
import
com.ctrip.framework.apollo.biz.MockBeanFactory
;
import
com.ctrip.framework.apollo.biz.entity.ServerConfig
;
import
com.ctrip.framework.apollo.biz.repository.ServerConfigRepository
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
...
...
@@ -45,19 +46,19 @@ public class BizDBPropertySourceTest extends AbstractUnitTest {
//cluster config
String
cluster
=
"cluster"
;
configs
.
add
(
create
ServerConfig
(
clusterConfigKey
,
clusterConfigValue
,
cluster
));
configs
.
add
(
MockBeanFactory
.
mock
ServerConfig
(
clusterConfigKey
,
clusterConfigValue
,
cluster
));
String
dc
=
"dc"
;
configs
.
add
(
create
ServerConfig
(
clusterConfigKey
,
clusterConfigValue
+
"dc"
,
dc
));
configs
.
add
(
create
ServerConfig
(
clusterConfigKey
,
clusterConfigValue
+
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
configs
.
add
(
MockBeanFactory
.
mock
ServerConfig
(
clusterConfigKey
,
clusterConfigValue
+
"dc"
,
dc
));
configs
.
add
(
MockBeanFactory
.
mock
ServerConfig
(
clusterConfigKey
,
clusterConfigValue
+
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
));
//dc config
configs
.
add
(
create
ServerConfig
(
dcConfigKey
,
dcConfigValue
,
dc
));
configs
.
add
(
create
ServerConfig
(
dcConfigKey
,
dcConfigValue
+
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
configs
.
add
(
MockBeanFactory
.
mock
ServerConfig
(
dcConfigKey
,
dcConfigValue
,
dc
));
configs
.
add
(
MockBeanFactory
.
mock
ServerConfig
(
dcConfigKey
,
dcConfigValue
+
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
));
//default config
configs
.
add
(
create
ServerConfig
(
defaultKey
,
defaultValue
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
));
configs
.
add
(
MockBeanFactory
.
mock
ServerConfig
(
defaultKey
,
defaultValue
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
));
System
.
setProperty
(
ConfigConsts
.
APOLLO_CLUSTER_KEY
,
cluster
);
...
...
@@ -99,14 +100,5 @@ public class BizDBPropertySourceTest extends AbstractUnitTest {
assertNull
(
propertySource
.
getProperty
(
"noKey"
));
}
private
ServerConfig
createServerConfig
(
String
key
,
String
value
,
String
cluster
)
{
ServerConfig
config
=
new
ServerConfig
();
config
.
setKey
(
key
);
config
.
setValue
(
value
);
config
.
setCluster
(
cluster
);
return
config
;
}
}
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/NamespaceServiceIntegrationTest.java
0 → 100644
View file @
a684730f
package
com
.
ctrip
.
framework
.
apollo
.
biz
.
service
;
import
com.ctrip.framework.apollo.biz.AbstractIntegrationTest
;
import
com.ctrip.framework.apollo.biz.entity.Cluster
;
import
com.ctrip.framework.apollo.biz.entity.Commit
;
import
com.ctrip.framework.apollo.biz.entity.InstanceConfig
;
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.entity.ReleaseHistory
;
import
com.ctrip.framework.apollo.biz.repository.InstanceConfigRepository
;
import
com.ctrip.framework.apollo.common.entity.AppNamespace
;
import
org.junit.Test
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.PageRequest
;
import
org.springframework.test.context.jdbc.Sql
;
import
java.util.List
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
public
class
NamespaceServiceIntegrationTest
extends
AbstractIntegrationTest
{
@Autowired
private
NamespaceService
namespaceService
;
@Autowired
private
ItemService
itemService
;
@Autowired
private
CommitService
commitService
;
@Autowired
private
AppNamespaceService
appNamespaceService
;
@Autowired
private
ClusterService
clusterService
;
@Autowired
private
ReleaseService
releaseService
;
@Autowired
private
ReleaseHistoryService
releaseHistoryService
;
@Autowired
private
InstanceConfigRepository
instanceConfigRepository
;
private
String
testApp
=
"testApp"
;
private
String
testCluster
=
"default"
;
private
String
testChildCluster
=
"child-cluster"
;
private
String
testPrivateNamespace
=
"application"
;
private
String
testUser
=
"apollo"
;
@Test
@Sql
(
scripts
=
"/sql/namespace-test.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
BEFORE_TEST_METHOD
)
@Sql
(
scripts
=
"/sql/clean.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
AFTER_TEST_METHOD
)
public
void
testDeleteNamespace
()
{
Namespace
namespace
=
new
Namespace
();
namespace
.
setAppId
(
testApp
);
namespace
.
setClusterName
(
testCluster
);
namespace
.
setNamespaceName
(
testPrivateNamespace
);
namespace
.
setId
(
1
);
namespaceService
.
deleteNamespace
(
namespace
,
testUser
);
List
<
Item
>
items
=
itemService
.
findItems
(
testApp
,
testCluster
,
testPrivateNamespace
);
List
<
Commit
>
commits
=
commitService
.
find
(
testApp
,
testCluster
,
testPrivateNamespace
,
new
PageRequest
(
0
,
10
));
AppNamespace
appNamespace
=
appNamespaceService
.
findOne
(
testApp
,
testPrivateNamespace
);
List
<
Cluster
>
childClusters
=
clusterService
.
findChildClusters
(
testApp
,
testCluster
);
InstanceConfig
instanceConfig
=
instanceConfigRepository
.
findOne
(
1L
);
List
<
Release
>
parentNamespaceReleases
=
releaseService
.
findActiveReleases
(
testApp
,
testCluster
,
testPrivateNamespace
,
new
PageRequest
(
0
,
10
));
List
<
Release
>
childNamespaceReleases
=
releaseService
.
findActiveReleases
(
testApp
,
testChildCluster
,
testPrivateNamespace
,
new
PageRequest
(
0
,
10
));
Page
<
ReleaseHistory
>
releaseHistories
=
releaseHistoryService
.
findReleaseHistoriesByNamespace
(
testApp
,
testCluster
,
testPrivateNamespace
,
new
PageRequest
(
0
,
10
));
assertEquals
(
0
,
items
.
size
());
assertEquals
(
0
,
commits
.
size
());
assertNotNull
(
appNamespace
);
assertEquals
(
0
,
childClusters
.
size
());
assertEquals
(
0
,
parentNamespaceReleases
.
size
());
assertEquals
(
0
,
childNamespaceReleases
.
size
());
assertTrue
(!
releaseHistories
.
hasContent
());
assertNull
(
instanceConfig
);
}
}
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/NamespaceServiceTest.java
View file @
a684730f
package
com
.
ctrip
.
framework
.
apollo
.
biz
.
service
;
import
com.ctrip.framework.apollo.biz.AbstractIntegrationTest
;
import
com.ctrip.framework.apollo.biz.entity.Cluster
;
import
com.ctrip.framework.apollo.biz.entity.Commit
;
import
com.ctrip.framework.apollo.biz.entity.InstanceConfig
;
import
com.ctrip.framework.apollo.biz.entity.Item
;
import
com.ctrip.framework.apollo.biz.AbstractUnitTest
;
import
com.ctrip.framework.apollo.biz.MockBeanFactory
;
import
com.ctrip.framework.apollo.biz.entity.Namespace
;
import
com.ctrip.framework.apollo.biz.entity.Release
;
import
com.ctrip.framework.apollo.biz.entity.ReleaseHistory
;
import
com.ctrip.framework.apollo.biz.repository.InstanceConfigRepository
;
import
com.ctrip.framework.apollo.biz.repository.NamespaceRepository
;
import
com.ctrip.framework.apollo.common.entity.AppNamespace
;
import
com.ctrip.framework.apollo.common.exception.BadRequestException
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
org.junit.Test
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.domain.Page
;
import
org.mockito.InjectMocks
;
import
org.mockito.Mock
;
import
org.mockito.Spy
;
import
org.springframework.data.domain.PageRequest
;
import
org.springframework.
test.context.jdbc.Sql
;
import
org.springframework.
data.domain.Pageable
;
import
java.util.Arrays
;
import
java.util.List
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
mockito
.
Mockito
.
doReturn
;
import
static
org
.
mockito
.
Mockito
.
when
;
public
class
NamespaceServiceTest
extends
Abstract
Integration
Test
{
public
class
NamespaceServiceTest
extends
Abstract
Unit
Test
{
@Mock
private
AppNamespaceService
appNamespaceService
;
@Mock
private
NamespaceRepository
namespaceRepository
;
@Autowired
@Spy
@InjectMocks
private
NamespaceService
namespaceService
;
@Autowired
private
ItemService
itemService
;
@Autowired
private
CommitService
commitService
;
@Autowired
private
AppNamespaceService
appNamespaceService
;
@Autowired
private
ClusterService
clusterService
;
@Autowired
private
ReleaseService
releaseService
;
@Autowired
private
ReleaseHistoryService
releaseHistoryService
;
@Autowired
private
InstanceConfigRepository
instanceConfigRepository
;
private
String
testApp
=
"testApp"
;
private
String
testCluster
=
"default"
;
private
String
testChildCluster
=
"child-cluster"
;
private
String
testPrivateNamespace
=
"application"
;
private
String
testUser
=
"apollo"
;
private
String
testPublicAppNamespace
=
"publicAppNamespace"
;
@Test
(
expected
=
BadRequestException
.
class
)
public
void
testFindPublicAppNamespaceWithWrongNamespace
()
{
Pageable
page
=
new
PageRequest
(
0
,
10
);
when
(
appNamespaceService
.
findPublicNamespaceByName
(
testPublicAppNamespace
)).
thenReturn
(
null
);
namespaceService
.
findPublicAppNamespaceAllNamespaces
(
testPublicAppNamespace
,
page
);
}
@Test
@Sql
(
scripts
=
"/sql/namespace-test.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
BEFORE_TEST_METHOD
)
@Sql
(
scripts
=
"/sql/clean.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
AFTER_TEST_METHOD
)
public
void
testDeleteNamespace
()
{
Namespace
namespace
=
new
Namespace
();
namespace
.
setAppId
(
testApp
);
namespace
.
setClusterName
(
testCluster
);
namespace
.
setNamespaceName
(
testPrivateNamespace
);
namespace
.
setId
(
1
);
namespaceService
.
deleteNamespace
(
namespace
,
testUser
);
List
<
Item
>
items
=
itemService
.
findItems
(
testApp
,
testCluster
,
testPrivateNamespace
);
List
<
Commit
>
commits
=
commitService
.
find
(
testApp
,
testCluster
,
testPrivateNamespace
,
new
PageRequest
(
0
,
10
));
AppNamespace
appNamespace
=
appNamespaceService
.
findOne
(
testApp
,
testPrivateNamespace
);
List
<
Cluster
>
childClusters
=
clusterService
.
findChildClusters
(
testApp
,
testCluster
);
InstanceConfig
instanceConfig
=
instanceConfigRepository
.
findOne
(
1L
);
List
<
Release
>
parentNamespaceReleases
=
releaseService
.
findActiveReleases
(
testApp
,
testCluster
,
testPrivateNamespace
,
new
PageRequest
(
0
,
10
));
List
<
Release
>
childNamespaceReleases
=
releaseService
.
findActiveReleases
(
testApp
,
testChildCluster
,
testPrivateNamespace
,
new
PageRequest
(
0
,
10
));
Page
<
ReleaseHistory
>
releaseHistories
=
releaseHistoryService
.
findReleaseHistoriesByNamespace
(
testApp
,
testCluster
,
testPrivateNamespace
,
new
PageRequest
(
0
,
10
));
assertEquals
(
0
,
items
.
size
());
assertEquals
(
0
,
commits
.
size
());
assertNotNull
(
appNamespace
);
assertEquals
(
0
,
childClusters
.
size
());
assertEquals
(
0
,
parentNamespaceReleases
.
size
());
assertEquals
(
0
,
childNamespaceReleases
.
size
());
assertTrue
(!
releaseHistories
.
hasContent
());
assertNull
(
instanceConfig
);
public
void
testFindPublicAppNamespace
()
{
AppNamespace
publicAppNamespace
=
MockBeanFactory
.
mockAppNamespace
(
null
,
testPublicAppNamespace
,
true
);
when
(
appNamespaceService
.
findPublicNamespaceByName
(
testPublicAppNamespace
)).
thenReturn
(
publicAppNamespace
);
Namespace
firstParentNamespace
=
MockBeanFactory
.
mockNamespace
(
"app"
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
testPublicAppNamespace
);
Namespace
secondParentNamespace
=
MockBeanFactory
.
mockNamespace
(
"app1"
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
testPublicAppNamespace
);
Namespace
childNamespace
=
MockBeanFactory
.
mockNamespace
(
"app2"
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
testPublicAppNamespace
);
Pageable
page
=
new
PageRequest
(
0
,
10
);
when
(
namespaceRepository
.
findByNamespaceName
(
testPublicAppNamespace
,
page
))
.
thenReturn
(
Arrays
.
asList
(
firstParentNamespace
,
secondParentNamespace
));
doReturn
(
false
).
when
(
namespaceService
).
isChildNamespace
(
firstParentNamespace
);
doReturn
(
false
).
when
(
namespaceService
).
isChildNamespace
(
secondParentNamespace
);
doReturn
(
true
).
when
(
namespaceService
).
isChildNamespace
(
childNamespace
);
List
<
Namespace
>
namespaces
=
namespaceService
.
findPublicAppNamespaceAllNamespaces
(
testPublicAppNamespace
,
page
);
assertEquals
(
2
,
namespaces
.
size
());
}
}
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/ReleaseServiceTest.java
View file @
a684730f
...
...
@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
import
com.google.common.collect.Sets
;
import
com.ctrip.framework.apollo.biz.AbstractUnitTest
;
import
com.ctrip.framework.apollo.biz.MockBeanFactory
;
import
com.ctrip.framework.apollo.biz.entity.Release
;
import
com.ctrip.framework.apollo.biz.repository.ReleaseRepository
;
import
com.ctrip.framework.apollo.common.exception.BadRequestException
;
...
...
@@ -116,9 +117,8 @@ public class ReleaseServiceTest extends AbstractUnitTest {
String
someReleaseKey
=
"someKey"
;
String
someValidConfiguration
=
"{\"apollo.bar\": \"foo\"}"
;
Release
someRelease
=
assembleRelease
(
someReleaseId
,
someReleaseKey
,
someAppId
,
someClusterName
,
Release
someRelease
=
MockBeanFactory
.
mockRelease
(
someReleaseId
,
someReleaseKey
,
someAppId
,
someClusterName
,
someNamespaceName
,
someValidConfiguration
);
...
...
@@ -189,18 +189,5 @@ public class ReleaseServiceTest extends AbstractUnitTest {
assertEquals
(
someReleases
,
result
);
}
private
Release
assembleRelease
(
long
releaseId
,
String
releaseKey
,
String
appId
,
String
clusterName
,
String
groupName
,
String
configurations
)
{
Release
release
=
new
Release
();
release
.
setId
(
releaseId
);
release
.
setReleaseKey
(
releaseKey
);
release
.
setAppId
(
appId
);
release
.
setClusterName
(
clusterName
);
release
.
setNamespaceName
(
groupName
);
release
.
setConfigurations
(
configurations
);
return
release
;
}
}
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/utils/ReleaseKeyGeneratorTest.java
View file @
a684730f
...
...
@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.biz.utils;
import
com.google.common.collect.Sets
;
import
com.ctrip.framework.apollo.biz.MockBeanFactory
;
import
com.ctrip.framework.apollo.biz.entity.Namespace
;
import
org.junit.Test
;
...
...
@@ -29,8 +30,8 @@ public class ReleaseKeyGeneratorTest {
String
anotherAppId
=
"anotherAppId"
;
Namespace
namespace
=
assemble
Namespace
(
someAppId
,
someCluster
,
someNamespace
);
Namespace
anotherNamespace
=
assemble
Namespace
(
anotherAppId
,
someCluster
,
someNamespace
);
Namespace
namespace
=
MockBeanFactory
.
mock
Namespace
(
someAppId
,
someCluster
,
someNamespace
);
Namespace
anotherNamespace
=
MockBeanFactory
.
mock
Namespace
(
anotherAppId
,
someCluster
,
someNamespace
);
int
generateTimes
=
50000
;
Set
<
String
>
releaseKeys
=
Sets
.
newConcurrentHashSet
();
...
...
@@ -63,11 +64,4 @@ public class ReleaseKeyGeneratorTest {
};
}
private
Namespace
assembleNamespace
(
String
appId
,
String
cluster
,
String
namespaceName
)
{
Namespace
namespace
=
new
Namespace
();
namespace
.
setAppId
(
appId
);
namespace
.
setClusterName
(
cluster
);
namespace
.
setNamespaceName
(
namespaceName
);
return
namespace
;
}
}
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/api/AdminServiceAPI.java
View file @
a684730f
...
...
@@ -20,6 +20,7 @@ import com.ctrip.framework.apollo.core.enums.Env;
import
org.springframework.boot.actuate.health.Health
;
import
org.springframework.core.ParameterizedTypeReference
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.http.HttpEntity
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.MediaType
;
...
...
@@ -81,10 +82,12 @@ public class AdminServiceAPI {
NamespaceDTO
.
class
,
appId
,
clusterName
,
namespaceName
);
}
public
NamespaceDTO
findPublicNamespaceForAssociatedNamespace
(
Env
env
,
String
appId
,
String
clusterName
,
String
namespaceName
)
{
public
NamespaceDTO
findPublicNamespaceForAssociatedNamespace
(
Env
env
,
String
appId
,
String
clusterName
,
String
namespaceName
)
{
return
restTemplate
.
get
(
env
,
"apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/associated-public-namespace"
,
NamespaceDTO
.
class
,
appId
,
clusterName
,
namespaceName
);
restTemplate
.
get
(
env
,
"apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/associated-public-namespace"
,
NamespaceDTO
.
class
,
appId
,
clusterName
,
namespaceName
);
}
public
NamespaceDTO
createNamespace
(
Env
env
,
NamespaceDTO
namespace
)
{
...
...
@@ -109,6 +112,22 @@ public class AdminServiceAPI {
return
restTemplate
.
get
(
env
,
"apps/{appId}/namespaces/publish_info"
,
typeReference
,
appId
).
getBody
();
}
public
List
<
NamespaceDTO
>
getPublicAppNamespaceAllNamespaces
(
Env
env
,
String
publicNamespaceName
,
int
page
,
int
size
)
{
NamespaceDTO
[]
namespaceDTOs
=
restTemplate
.
get
(
env
,
"/appnamespaces/{publicNamespaceName}/namespaces?page={page}&size={size}"
,
NamespaceDTO
[].
class
,
publicNamespaceName
,
page
,
size
);
return
Arrays
.
asList
(
namespaceDTOs
);
}
public
int
countPublicAppNamespaceAssociatedNamespaces
(
Env
env
,
String
publicNamesapceName
)
{
Integer
count
=
restTemplate
.
get
(
env
,
"/appnamespaces/{publicNamespaceName}/associated-namespaces/count"
,
Integer
.
class
,
publicNamesapceName
);
return
count
==
null
?
0
:
count
;
}
}
@Service
...
...
@@ -230,7 +249,8 @@ public class AdminServiceAPI {
}
public
ReleaseDTO
createRelease
(
String
appId
,
Env
env
,
String
clusterName
,
String
namespace
,
String
releaseName
,
String
releaseComment
,
String
operator
,
boolean
isEmergencyPublish
)
{
String
releaseName
,
String
releaseComment
,
String
operator
,
boolean
isEmergencyPublish
)
{
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
setContentType
(
MediaType
.
parseMediaType
(
MediaType
.
APPLICATION_FORM_URLENCODED_VALUE
+
";charset=UTF-8"
));
MultiValueMap
<
String
,
String
>
parameters
=
new
LinkedMultiValueMap
<>();
...
...
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java
View file @
a684730f
...
...
@@ -21,14 +21,16 @@ public class PermissionValidator {
return
rolePermissionService
.
userHasPermission
(
userInfoHolder
.
getUser
().
getUserId
(),
PermissionType
.
MODIFY_NAMESPACE
,
RoleUtils
.
buildNamespaceTargetId
(
appId
,
namespaceName
));
}
public
boolean
hasReleaseNamespacePermission
(
String
appId
,
String
namespaceName
)
{
return
rolePermissionService
.
userHasPermission
(
userInfoHolder
.
getUser
().
getUserId
(),
PermissionType
.
RELEASE_NAMESPACE
,
RoleUtils
.
buildNamespaceTargetId
(
appId
,
namespaceName
));
}
public
boolean
hasDeleteNamespacePermission
(
String
appId
)
{
return
hasAssignRolePermission
(
appId
)
||
isSuperAdmin
();
}
public
boolean
hasOperateNamespacePermission
(
String
appId
,
String
namespaceName
){
...
...
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java
View file @
a684730f
...
...
@@ -35,6 +35,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
...
...
@@ -45,7 +46,7 @@ import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkM
@RestController
public
class
NamespaceController
{
Logger
logger
=
LoggerFactory
.
getLogger
(
NamespaceController
.
class
);
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
NamespaceController
.
class
);
@Autowired
private
AppService
appService
;
...
...
@@ -130,11 +131,13 @@ public class NamespaceController {
return
ResponseEntity
.
ok
().
build
();
}
@PreAuthorize
(
value
=
"@permissionValidator.
isSuperAdmin(
)"
)
@PreAuthorize
(
value
=
"@permissionValidator.
hasDeleteNamespacePermission(#appId
)"
)
@RequestMapping
(
value
=
"/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName:.+}"
,
method
=
RequestMethod
.
DELETE
)
public
ResponseEntity
<
Void
>
deleteNamespace
(
@PathVariable
String
appId
,
@PathVariable
String
env
,
@PathVariable
String
clusterName
,
@PathVariable
String
namespaceName
)
{
namespaceService
.
deleteNamespace
(
appId
,
Env
.
valueOf
(
env
),
clusterName
,
namespaceName
);
return
ResponseEntity
.
ok
().
build
();
}
...
...
@@ -183,4 +186,14 @@ public class NamespaceController {
return
namespaceService
.
getNamespacesPublishInfo
(
appId
);
}
@RequestMapping
(
value
=
"/envs/{env}/appnamespaces/{publicNamespaceName}/namespaces"
,
method
=
RequestMethod
.
GET
)
public
List
<
NamespaceDTO
>
getPublicAppNamespaceAllNamespaces
(
@PathVariable
String
env
,
@PathVariable
String
publicNamespaceName
,
@RequestParam
(
name
=
"page"
,
defaultValue
=
"0"
)
int
page
,
@RequestParam
(
name
=
"size"
,
defaultValue
=
"10"
)
int
size
)
{
return
namespaceService
.
getPublicAppNamespaceAllNamespaces
(
Env
.
fromString
(
env
),
publicNamespaceName
,
page
,
size
);
}
}
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/NamespaceBranchService.java
View file @
a684730f
...
...
@@ -9,7 +9,6 @@ import com.ctrip.framework.apollo.common.exception.BadRequestException;
import
com.ctrip.framework.apollo.core.enums.Env
;
import
com.ctrip.framework.apollo.portal.api.AdminServiceAPI
;
import
com.ctrip.framework.apollo.portal.component.ItemsComparator
;
import
com.ctrip.framework.apollo.portal.component.PermissionValidator
;
import
com.ctrip.framework.apollo.portal.constant.CatEventType
;
import
com.ctrip.framework.apollo.portal.entity.bo.NamespaceBO
;
import
com.ctrip.framework.apollo.portal.spi.UserInfoHolder
;
...
...
@@ -37,8 +36,6 @@ public class NamespaceBranchService {
private
AdminServiceAPI
.
NamespaceBranchAPI
namespaceBranchAPI
;
@Autowired
private
ReleaseService
releaseService
;
@Autowired
private
PermissionValidator
permissionValidator
;
@Transactional
...
...
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/NamespaceService.java
View file @
a684730f
package
com
.
ctrip
.
framework
.
apollo
.
portal
.
service
;
import
com.ctrip.framework.apollo.portal.component.config.PortalConfig
;
import
com.google.common.collect.Maps
;
import
com.google.gson.Gson
;
...
...
@@ -36,20 +37,24 @@ public class NamespaceService {
private
Logger
logger
=
LoggerFactory
.
getLogger
(
NamespaceService
.
class
);
private
Gson
gson
=
new
Gson
();
@Autowired
private
PortalConfig
portalConfig
;
@Autowired
private
PortalSettings
portalSettings
;
@Autowired
private
UserInfoHolder
userInfoHolder
;
@Autowired
private
AdminServiceAPI
.
NamespaceAPI
namespaceAPI
;
@Autowired
private
ItemService
itemService
;
@Autowired
private
ReleaseService
releaseService
;
@Autowired
private
AdminServiceAPI
.
NamespaceAPI
namespaceAPI
;
@Autowired
private
AppNamespaceService
appNamespaceService
;
@Autowired
private
PortalConfig
portalConfig
;
private
InstanceService
instanceService
;
@Autowired
private
PortalSettings
portalSettings
;
private
NamespaceBranchService
branchService
;
public
NamespaceDTO
createNamespace
(
Env
env
,
NamespaceDTO
namespace
)
{
...
...
@@ -69,9 +74,27 @@ public class NamespaceService {
@Transactional
public
void
deleteNamespace
(
String
appId
,
Env
env
,
String
clusterName
,
String
namespaceName
)
{
//1. check private namespace
AppNamespace
appNamespace
=
appNamespaceService
.
findByAppIdAndName
(
appId
,
namespaceName
);
if
(
appNamespace
!=
null
&&
!
appNamespace
.
isPublic
())
{
throw
new
BadRequestException
(
"private namespace can not be deleted"
);
throw
new
BadRequestException
(
"Private namespace can not be deleted"
);
}
//2. check parent namespace has not instances
if
(
namespaceHasInstances
(
appId
,
env
,
clusterName
,
namespaceName
))
{
throw
new
BadRequestException
(
"Can not delete namespace because namespace has active instances"
);
}
//3. check child namespace has not instances
NamespaceDTO
childNamespace
=
branchService
.
findBranchBaseInfo
(
appId
,
env
,
clusterName
,
namespaceName
);
if
(
childNamespace
!=
null
&&
namespaceHasInstances
(
appId
,
env
,
childNamespace
.
getClusterName
(),
namespaceName
))
{
throw
new
BadRequestException
(
"Can not delete namespace because namespace's branch has active instances"
);
}
//4. check public namespace has not associated namespace
if
(
appNamespace
!=
null
&&
publicAppNamespaceHasAssociatedNamespace
(
namespaceName
,
env
))
{
throw
new
BadRequestException
(
"Can not delete public namespace which has associated namespaces"
);
}
String
operator
=
userInfoHolder
.
getUser
().
getUserId
();
...
...
@@ -79,7 +102,6 @@ public class NamespaceService {
namespaceAPI
.
deleteNamespace
(
env
,
appId
,
clusterName
,
namespaceName
,
operator
);
}
public
NamespaceDTO
loadNamespaceBaseInfo
(
String
appId
,
Env
env
,
String
clusterName
,
String
namespaceName
)
{
NamespaceDTO
namespace
=
namespaceAPI
.
loadNamespace
(
appId
,
env
,
clusterName
,
namespaceName
);
if
(
namespace
==
null
)
{
...
...
@@ -115,6 +137,11 @@ public class NamespaceService {
return
namespaceBOs
;
}
public
List
<
NamespaceDTO
>
getPublicAppNamespaceAllNamespaces
(
Env
env
,
String
publicNamespaceName
,
int
page
,
int
size
)
{
return
namespaceAPI
.
getPublicAppNamespaceAllNamespaces
(
env
,
publicNamespaceName
,
page
,
size
);
}
public
NamespaceBO
loadNamespaceBO
(
String
appId
,
Env
env
,
String
clusterName
,
String
namespaceName
)
{
NamespaceDTO
namespace
=
namespaceAPI
.
loadNamespace
(
appId
,
env
,
clusterName
,
namespaceName
);
if
(
namespace
==
null
)
{
...
...
@@ -123,10 +150,18 @@ public class NamespaceService {
return
transformNamespace2BO
(
env
,
namespace
);
}
public
boolean
namespaceHasInstances
(
String
appId
,
Env
env
,
String
clusterName
,
String
namespaceName
)
{
return
instanceService
.
getInstanceCountByNamepsace
(
appId
,
env
,
clusterName
,
namespaceName
)
>
0
;
}
public
boolean
publicAppNamespaceHasAssociatedNamespace
(
String
publicNamespaceName
,
Env
env
)
{
return
namespaceAPI
.
countPublicAppNamespaceAssociatedNamespaces
(
env
,
publicNamespaceName
)
>
0
;
}
public
NamespaceBO
findPublicNamespaceForAssociatedNamespace
(
Env
env
,
String
appId
,
String
clusterName
,
String
namespaceName
)
{
NamespaceDTO
namespace
=
namespaceAPI
.
findPublicNamespaceForAssociatedNamespace
(
env
,
appId
,
clusterName
,
namespaceName
);
NamespaceDTO
namespace
=
namespaceAPI
.
findPublicNamespaceForAssociatedNamespace
(
env
,
appId
,
clusterName
,
namespaceName
);
return
transformNamespace2BO
(
env
,
namespace
);
}
...
...
@@ -135,7 +170,7 @@ public class NamespaceService {
Map
<
String
,
Map
<
String
,
Boolean
>>
result
=
Maps
.
newHashMap
();
Set
<
Env
>
envs
=
portalConfig
.
publishTipsSupportedEnvs
();
for
(
Env
env:
envs
)
{
for
(
Env
env
:
envs
)
{
if
(
portalSettings
.
isEnvActive
(
env
))
{
result
.
put
(
env
.
toString
(),
namespaceAPI
.
getNamespacePublishInfo
(
env
,
appId
));
}
...
...
apollo-portal/src/main/resources/static/config.html
View file @
a684730f
...
...
@@ -231,6 +231,8 @@
<publishdenymodal
env=
"pageContext.env"
></publishdenymodal>
<deletenamespacemodal
env=
"pageContext.env"
></deletenamespacemodal>
<apolloconfirmdialog
apollo-dialog-id=
"'deleteConfirmDialog'"
apollo-title=
"'删除配置'"
apollo-detail=
"'确定要删除配置吗?'"
apollo-show-cancel-btn=
"true"
apollo-confirm=
"deleteItem"
></apolloconfirmdialog>
...
...
@@ -274,6 +276,31 @@
apollo-detail=
"'灰度版本还没有配置任何灰度规则,请配置灰度规则'"
>
</apolloconfirmdialog>
<apolloconfirmdialog
apollo-dialog-id=
"'deleteNamespaceDenyForMasterInstanceDialog'"
apollo-title=
"'删除Namespace警告信息'"
apollo-detail=
"'发现有 <b>' + deleteNamespaceContext.namespace.instancesCount +
'</b> 个实例正在使用Namespace(' + deleteNamespaceContext.namespace.baseInfo.namespaceName +
'),删除Namespace将导致实例获取不到配置。<br>
请到 <ins>“实例列表”</ins> 确认实例信息,如已确认删除Namespace将不会导致实例异常,
请发送邮件至<ins> <a href=\'mailto:rdkjapollo@ctrip.com\'>Apollo团队(rdkjapollo@ctrip.com)</a></ins> 删除Namespace。'"
apollo-confirm=
"continueDeleteNamespace"
>
</apolloconfirmdialog>
<apolloconfirmdialog
apollo-dialog-id=
"'deleteNamespaceDenyForBranchInstanceDialog'"
apollo-title=
"'删除Namespace警告信息'"
apollo-detail=
"'发现有 <b>' + deleteNamespaceContext.namespace.branch.latestReleaseInstances.total
+ '</b> 个实例正在使用Namespace(' + deleteNamespaceContext.namespace.baseInfo.namespaceName +
')灰度版本的配置,删除Namespace将导致实例获取不到配置。<br>
请到 <ins>“灰度版本” => “实例列表”</ins> 确认实例信息,如已确认删除Namespace将不会导致实例异常,
请发送邮件至<ins> <a href=\'mailto:rdkjapollo@ctrip.com\'>Apollo团队(rdkjapollo@ctrip.com)</a></ins> 删除Namespace。'"
apollo-confirm=
"continueDeleteNamespace"
>
</apolloconfirmdialog>
<apolloconfirmdialog
apollo-dialog-id=
"'deleteNamespaceDenyForPublicNamespaceDialog'"
apollo-title=
"'删除Namespace失败提示'"
apollo-detail=
"deleteNamespaceContext.detailReason"
>
</apolloconfirmdialog>
<div
class=
"modal fade"
id=
"createBranchTips"
tabindex=
"-1"
role=
"dialog"
>
<div
class=
"modal-dialog"
role=
"document"
>
...
...
@@ -375,6 +402,7 @@
<script
type=
"application/javascript"
src=
"scripts/directive/gray-release-rules-modal-directive.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/directive/merge-and-publish-modal-directive.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/directive/publish-deny-modal-directive.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/directive/delete-namespace-modal-directive.js"
></script>
<!--controller-->
<script
type=
"application/javascript"
src=
"scripts/controller/config/ConfigNamespaceController.js"
></script>
...
...
apollo-portal/src/main/resources/static/img/delete.png
View replaced file @
202363b5
View file @
a684730f
3.39 KB
|
W:
|
H:
3.96 KB
|
W:
|
H:
2-up
Swipe
Onion skin
apollo-portal/src/main/resources/static/img/operate.png
0 → 100644
View file @
a684730f
4.66 KB
apollo-portal/src/main/resources/static/img/rollback.png
View replaced file @
202363b5
View file @
a684730f
2.67 KB
|
W:
|
H:
2.32 KB
|
W:
|
H:
2-up
Swipe
Onion skin
apollo-portal/src/main/resources/static/img/time.png
deleted
100644 → 0
View file @
202363b5
4.2 KB
apollo-portal/src/main/resources/static/img/title.png
deleted
100644 → 0
View file @
202363b5
2.22 KB
apollo-portal/src/main/resources/static/img/user.png
deleted
100644 → 0
View file @
202363b5
4.2 KB
apollo-portal/src/main/resources/static/scripts/controller/config/ConfigNamespaceController.js
View file @
a684730f
...
...
@@ -337,6 +337,36 @@ function controller($rootScope, $scope, toastr, AppUtil, EventManager, ConfigSer
}
EventManager
.
subscribe
(
EventManager
.
EventType
.
DELETE_NAMESPACE_FAILED
,
function
(
context
)
{
$scope
.
deleteNamespaceContext
=
context
;
if
(
context
.
reason
==
'
master_instance
'
)
{
AppUtil
.
showModal
(
'
#deleteNamespaceDenyForMasterInstanceDialog
'
);
}
else
if
(
context
.
reason
==
'
branch_instance
'
)
{
AppUtil
.
showModal
(
'
#deleteNamespaceDenyForBranchInstanceDialog
'
);
}
else
if
(
context
.
reason
==
'
public_namespace
'
)
{
var
otherAppAssociatedNamespaces
=
context
.
otherAppAssociatedNamespaces
;
var
namespaceTips
=
[];
otherAppAssociatedNamespaces
.
forEach
(
function
(
namespace
)
{
var
appId
=
namespace
.
appId
;
var
clusterName
=
namespace
.
clusterName
;
var
url
=
'
/config.html?#/appid=
'
+
appId
+
'
&env=
'
+
$scope
.
pageContext
.
env
+
'
&cluster=
'
+
clusterName
;
namespaceTips
.
push
(
"
<a target='_blank' href=
\
'
"
+
url
+
"
\
'>AppId =
"
+
appId
+
"
, 集群 =
"
+
clusterName
+
"
, Namespace =
"
+
namespace
.
namespaceName
+
"
</a>
"
);
});
$scope
.
deleteNamespaceContext
.
detailReason
=
"
以下应用已关联此公共Namespace,必须先删除全部已关联的Namespace才能删除公共Namespace。<br>
"
+
namespaceTips
.
join
(
"
<br>
"
);
AppUtil
.
showModal
(
'
#deleteNamespaceDenyForPublicNamespaceDialog
'
);
}
});
new
Clipboard
(
'
.clipboard
'
);
}
...
...
apollo-portal/src/main/resources/static/scripts/directive/delete-namespace-modal-directive.js
0 → 100644
View file @
a684730f
directive_module
.
directive
(
'
deletenamespacemodal
'
,
deleteNamespaceModalDirective
);
function
deleteNamespaceModalDirective
(
$window
,
$q
,
toastr
,
AppUtil
,
EventManager
,
PermissionService
,
UserService
,
NamespaceService
)
{
return
{
restrict
:
'
E
'
,
templateUrl
:
'
../../views/component/delete-namespace-modal.html
'
,
transclude
:
true
,
replace
:
true
,
scope
:
{
env
:
'
=
'
},
link
:
function
(
scope
)
{
scope
.
doDeleteNamespace
=
doDeleteNamespace
;
EventManager
.
subscribe
(
EventManager
.
EventType
.
PRE_DELETE_NAMESPACE
,
function
(
context
)
{
var
toDeleteNamespace
=
context
.
namespace
;
scope
.
toDeleteNamespace
=
toDeleteNamespace
;
//1. check namespace is not private
if
(
!
checkNotPrivateNamespace
(
toDeleteNamespace
))
{
return
;
}
//2. check operator has master permission
checkPermission
(
toDeleteNamespace
).
then
(
function
()
{
//3. check namespace's master branch has not instances
if
(
!
checkMasterInstance
(
toDeleteNamespace
))
{
return
;
}
//4. check namespace's gray branch has not instances
if
(
!
checkBranchInstance
(
toDeleteNamespace
))
{
return
;
}
if
(
toDeleteNamespace
.
isLinkedNamespace
)
{
showDeleteNamespaceConfirmDialog
();
}
else
{
//5. check public namespace has not associated namespace
checkPublicNamespace
(
toDeleteNamespace
).
then
(
function
()
{
showDeleteNamespaceConfirmDialog
();
});
}
})
});
function
checkNotPrivateNamespace
(
namespace
)
{
if
(
!
namespace
.
isPublic
)
{
toastr
.
error
(
"
不能删除私有的Namespace
"
,
"
删除失败
"
);
return
false
;
}
return
true
;
}
function
checkPermission
(
namespace
)
{
var
d
=
$q
.
defer
();
UserService
.
load_user
().
then
(
function
(
currentUser
)
{
var
isAppMasterUser
=
false
;
PermissionService
.
get_app_role_users
(
namespace
.
baseInfo
.
appId
)
.
then
(
function
(
appRoleUsers
)
{
var
masterUsers
=
[];
appRoleUsers
.
masterUsers
.
forEach
(
function
(
user
)
{
masterUsers
.
push
(
user
.
userId
);
if
(
currentUser
.
userId
==
user
.
userId
)
{
isAppMasterUser
=
true
;
}
});
scope
.
masterUsers
=
masterUsers
;
scope
.
isAppMasterUser
=
isAppMasterUser
;
if
(
!
isAppMasterUser
)
{
toastr
.
error
(
"
您没有项目管理员权限,只有管理员才能删除Namespace,请找项目管理员 [
"
+
scope
.
masterUsers
.
join
(
"
,
"
)
+
"
] 删除Namespace
"
,
"
删除失败
"
);
d
.
reject
();
}
else
{
d
.
resolve
();
}
});
});
return
d
.
promise
;
}
function
checkMasterInstance
(
namespace
)
{
if
(
namespace
.
instancesCount
>
0
)
{
EventManager
.
emit
(
EventManager
.
EventType
.
DELETE_NAMESPACE_FAILED
,
{
namespace
:
namespace
,
reason
:
'
master_instance
'
});
return
false
;
}
return
true
;
}
function
checkBranchInstance
(
namespace
)
{
if
(
namespace
.
hasBranch
&&
namespace
.
branch
.
latestReleaseInstances
.
total
>
0
)
{
EventManager
.
emit
(
EventManager
.
EventType
.
DELETE_NAMESPACE_FAILED
,
{
namespace
:
namespace
,
reason
:
'
branch_instance
'
});
return
false
;
}
return
true
;
}
function
checkPublicNamespace
(
namespace
)
{
var
d
=
$q
.
defer
();
var
publicAppId
=
namespace
.
baseInfo
.
appId
;
NamespaceService
.
getPublicAppNamespaceAllNamespaces
(
scope
.
env
,
namespace
.
baseInfo
.
namespaceName
,
0
,
20
)
.
then
(
function
(
associatedNamespaces
)
{
var
otherAppAssociatedNamespaces
=
[];
associatedNamespaces
.
forEach
(
function
(
associatedNamespace
)
{
if
(
associatedNamespace
.
appId
!=
publicAppId
)
{
otherAppAssociatedNamespaces
.
push
(
associatedNamespace
);
}
});
if
(
otherAppAssociatedNamespaces
.
length
)
{
EventManager
.
emit
(
EventManager
.
EventType
.
DELETE_NAMESPACE_FAILED
,
{
namespace
:
namespace
,
reason
:
'
public_namespace
'
,
otherAppAssociatedNamespaces
:
otherAppAssociatedNamespaces
});
d
.
reject
();
}
else
{
d
.
resolve
();
}
});
return
d
.
promise
;
}
function
showDeleteNamespaceConfirmDialog
()
{
AppUtil
.
showModal
(
'
#deleteNamespaceModal
'
);
}
function
doDeleteNamespace
()
{
var
toDeleteNamespace
=
scope
.
toDeleteNamespace
;
NamespaceService
.
deleteNamespace
(
toDeleteNamespace
.
baseInfo
.
appId
,
scope
.
env
,
toDeleteNamespace
.
baseInfo
.
clusterName
,
toDeleteNamespace
.
baseInfo
.
namespaceName
)
.
then
(
function
()
{
toastr
.
success
(
"
删除成功
"
);
setTimeout
(
function
()
{
$window
.
location
.
reload
();
},
1000
);
},
function
(
result
)
{
AppUtil
.
showErrorMsg
(
result
,
"
删除失败
"
);
})
}
}
}
}
apollo-portal/src/main/resources/static/scripts/directive/directive.js
View file @
a684730f
...
...
@@ -213,7 +213,7 @@ directive_module.directive('apollorequiredfield', function ($compile, $window) {
});
/** 确认框 */
directive_module
.
directive
(
'
apolloconfirmdialog
'
,
function
(
$compile
,
$window
)
{
directive_module
.
directive
(
'
apolloconfirmdialog
'
,
function
(
$compile
,
$window
,
$sce
)
{
return
{
restrict
:
'
E
'
,
templateUrl
:
'
../../views/component/confirm-dialog.html
'
,
...
...
@@ -225,15 +225,26 @@ directive_module.directive('apolloconfirmdialog', function ($compile, $window) {
detail
:
'
=apolloDetail
'
,
showCancelBtn
:
'
=apolloShowCancelBtn
'
,
doConfirm
:
'
=apolloConfirm
'
,
confirmBtnText
:
'
=?
'
,
cancel
:
'
=
'
},
link
:
function
(
scope
,
element
,
attrs
)
{
scope
.
$watch
(
"
detail
"
,
function
()
{
scope
.
detailAsHtml
=
$sce
.
trustAsHtml
(
scope
.
detail
);
});
if
(
!
scope
.
confirmBtnText
)
{
scope
.
confirmBtnText
=
'
确认
'
;
}
scope
.
confirm
=
function
()
{
if
(
scope
.
doConfirm
)
{
scope
.
doConfirm
();
}
}
};
}
}
...
...
apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js
View file @
a684730f
...
...
@@ -62,6 +62,8 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
scope
.
addRuleItem
=
addRuleItem
;
scope
.
editRuleItem
=
editRuleItem
;
scope
.
deleteNamespace
=
deleteNamespace
;
var
subscriberId
=
EventManager
.
subscribe
(
EventManager
.
EventType
.
UPDATE_GRAY_RELEASE_RULES
,
function
(
context
)
{
useRules
(
context
.
branch
);
...
...
@@ -81,11 +83,13 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
function
initNamespace
(
namespace
,
viewType
)
{
namespace
.
hasBranch
=
false
;
namespace
.
currentOperateBranch
=
'
master
'
;
namespace
.
isBranch
=
false
;
namespace
.
isLinkedNamespace
=
namespace
.
isPublic
?
namespace
.
parentAppId
!=
namespace
.
baseInfo
.
appId
:
false
;
namespace
.
showSearchInput
=
false
;
namespace
.
displayControl
=
{
currentOperateBranch
:
'
master
'
,
showSearchInput
:
false
};
namespace
.
viewItems
=
namespace
.
items
;
namespace
.
isPropertiesFormat
=
namespace
.
format
==
'
properties
'
;
namespace
.
isTextEditing
=
false
;
...
...
@@ -336,7 +340,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
if
(
branchName
!=
'
master
'
)
{
initRules
(
scope
.
namespace
.
branch
);
}
scope
.
namespace
.
currentOperateBranch
=
branchName
;
scope
.
namespace
.
displayControl
.
currentOperateBranch
=
branchName
;
//save to local storage
var
operateBranchStorage
=
JSON
.
parse
(
localStorage
.
getItem
(
operate_branch_storage_key
));
...
...
@@ -398,6 +402,7 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
}
function
loadInstanceInfo
(
namespace
)
{
var
size
=
20
;
if
(
namespace
.
isBranch
)
{
size
=
2000
;
...
...
@@ -780,6 +785,10 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
function
rollback
(
namespace
)
{
EventManager
.
emit
(
EventManager
.
EventType
.
PRE_ROLLBACK_NAMESPACE
,
{
namespace
:
namespace
});
}
function
deleteNamespace
(
namespace
)
{
EventManager
.
emit
(
EventManager
.
EventType
.
PRE_DELETE_NAMESPACE
,
{
namespace
:
namespace
});
}
setTimeout
(
function
()
{
scope
.
namespace
.
show
=
true
;
...
...
apollo-portal/src/main/resources/static/scripts/services/EventManager.js
View file @
a684730f
...
...
@@ -133,7 +133,10 @@ appService.service('EventManager', [function () {
EDIT_GRAY_RELEASE_RULES
:
'
edit_gray_release_rules
'
,
UPDATE_GRAY_RELEASE_RULES
:
'
update_gray_release_rules
'
,
PUBLISH_DENY
:
'
publish_deny
'
,
EMERGENCY_PUBLISH
:
'
emergency_publish
'
EMERGENCY_PUBLISH
:
'
emergency_publish
'
,
PRE_DELETE_NAMESPACE
:
'
pre_delete_namespace
'
,
DELETE_NAMESPACE
:
'
delete_namespace
'
,
DELETE_NAMESPACE_FAILED
:
'
delete_namespace_failed
'
}
}
...
...
apollo-portal/src/main/resources/static/scripts/services/NamespaceService.js
View file @
a684730f
...
...
@@ -18,6 +18,15 @@ appService.service("NamespaceService", ['$resource', '$q', function ($resource,
getNamespacePublishInfo
:
{
method
:
'
GET
'
,
url
:
'
/apps/:appId/namespaces/publish_info
'
},
deleteNamespace
:
{
method
:
'
DELETE
'
,
url
:
'
/apps/:appId/envs/:env/clusters/:clusterName/namespaces/:namespaceName
'
},
getPublicAppNamespaceAllNamespaces
:
{
method
:
'
GET
'
,
url
:
'
/envs/:env/appnamespaces/:publicNamespaceName/namespaces
'
,
isArray
:
true
}
});
...
...
@@ -63,16 +72,53 @@ appService.service("NamespaceService", ['$resource', '$q', function ($resource,
d
.
resolve
(
result
);
},
function
(
result
)
{
d
.
reject
(
result
);
})
});
return
d
.
promise
;
}
function
deleteNamespace
(
appId
,
env
,
clusterName
,
namespaceName
)
{
var
d
=
$q
.
defer
();
namespace_source
.
deleteNamespace
({
appId
:
appId
,
env
:
env
,
clusterName
:
clusterName
,
namespaceName
:
namespaceName
},
function
(
result
)
{
d
.
resolve
(
result
);
},
function
(
result
)
{
d
.
reject
(
result
);
});
return
d
.
promise
;
}
function
getPublicAppNamespaceAllNamespaces
(
env
,
publicNamespaceName
,
page
,
size
)
{
var
d
=
$q
.
defer
();
namespace_source
.
getPublicAppNamespaceAllNamespaces
({
env
:
env
,
publicNamespaceName
:
publicNamespaceName
,
page
:
page
,
size
:
size
},
function
(
result
)
{
d
.
resolve
(
result
);
},
function
(
result
)
{
d
.
reject
(
result
);
});
return
d
.
promise
;
}
return
{
find_public_namespaces
:
find_public_namespaces
,
createNamespace
:
createNamespace
,
createAppNamespace
:
createAppNamespace
,
getNamespacePublishInfo
:
getNamespacePublishInfo
getNamespacePublishInfo
:
getNamespacePublishInfo
,
deleteNamespace
:
deleteNamespace
,
getPublicAppNamespaceAllNamespaces
:
getPublicAppNamespaceAllNamespaces
}
}]);
apollo-portal/src/main/resources/static/scripts/services/UserService.js
View file @
a684730f
appService
.
service
(
'
UserService
'
,
[
'
$resource
'
,
'
$q
'
,
function
(
$resource
,
$q
)
{
var
user_resource
=
$resource
(
''
,
{},
{
load_user
:{
load_user
:
{
method
:
'
GET
'
,
url
:
'
/user
'
url
:
'
/user
'
},
find_users
:
{
method
:
'
GET
'
,
...
...
@@ -11,26 +11,30 @@ appService.service('UserService', ['$resource', '$q', function ($resource, $q) {
});
return
{
load_user
:
function
()
{
var
finished
=
false
;
var
d
=
$q
.
defer
();
user_resource
.
load_user
({
},
user_resource
.
load_user
({},
function
(
result
)
{
finished
=
true
;
d
.
resolve
(
result
);
},
function
(
result
)
{
d
.
reject
(
result
);
});
},
function
(
result
)
{
finished
=
true
;
d
.
reject
(
result
);
});
return
d
.
promise
;
},
find_users
:
function
(
keyword
)
{
var
d
=
$q
.
defer
();
user_resource
.
find_users
({
keyword
:
keyword
},
function
(
result
)
{
d
.
resolve
(
result
);
},
function
(
result
)
{
d
.
reject
(
result
);
});
keyword
:
keyword
},
function
(
result
)
{
d
.
resolve
(
result
);
},
function
(
result
)
{
d
.
reject
(
result
);
});
return
d
.
promise
;
}
}
...
...
apollo-portal/src/main/resources/static/styles/common-style.css
View file @
a684730f
...
...
@@ -790,3 +790,7 @@ table th {
background
:
#fff
;
}
.dropdown
:hover
.dropdown-menu
{
display
:
block
;
margin-top
:
0
;
}
apollo-portal/src/main/resources/static/views/component/confirm-dialog.html
View file @
a684730f
...
...
@@ -6,15 +6,14 @@
aria-hidden=
"true"
>
×
</span></button>
<h4
class=
"modal-title"
>
{{title}}
</h4>
</div>
<div
class=
"modal-body"
>
{{detail}}
<div
class=
"modal-body"
ng-bind-html=
"detailAsHtml"
>
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
class=
"btn btn-default"
data-dismiss=
"modal"
ng-show=
"showCancelBtn"
ng-click=
"cancel()"
>
取消
</button>
<button
type=
"button"
class=
"btn btn-danger"
data-dismiss=
"modal"
ng-click=
"confirm()"
>
确定
{{confirmBtnText}}
</button>
</div>
</div>
...
...
apollo-portal/src/main/resources/static/views/component/delete-namespace-modal.html
0 → 100644
View file @
a684730f
<div
id=
"deleteNamespaceModal"
class=
"modal fade"
>
<div
class=
"modal-dialog"
role=
"document"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header panel-primary"
>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"Close"
><span
aria-hidden=
"true"
>
×
</span></button>
<h4
class=
"modal-title"
>
删除Namespace
</h4>
</div>
<div
class=
"modal-body form-horizontal"
>
删除Namespace将导致实例获取不到此Namespace的配置,确定要删除吗?
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
class=
"btn btn-default"
data-dismiss=
"modal"
>
取消
</button>
<button
type=
"button"
class=
"btn btn-danger"
data-dismiss=
"modal"
ng-click=
"doDeleteNamespace()"
>
确认
</button>
</div>
</div>
</div>
</div>
apollo-portal/src/main/resources/static/views/component/namespace-panel-branch-tab.html
View file @
a684730f
<section
class=
"branch-panel-body"
ng-if=
"namespace.hasBranch && namespace.currentOperateBranch != 'master'"
>
<section
class=
"branch-panel-body"
ng-if=
"namespace.hasBranch && namespace.
displayControl.
currentOperateBranch != 'master'"
>
<!--main header-->
<header
class=
"panel-heading"
>
...
...
apollo-portal/src/main/resources/static/views/component/namespace-panel-header.html
View file @
a684730f
...
...
@@ -21,14 +21,14 @@
<div
class=
"col-md-8 pull-left"
>
<ul
class=
"nav nav-tabs"
>
<li
role=
"presentation"
>
<a
ng-class=
"{'node_active': namespace.currentOperateBranch == 'master'}"
<a
ng-class=
"{'node_active': namespace.
displayControl.
currentOperateBranch == 'master'}"
ng-click=
"switchBranch('master')"
>
<img
src=
"img/branch.png"
>
主版本
</a>
</li>
<li
role=
"presentation"
>
<a
ng-class=
"{'node_active': namespace.currentOperateBranch != 'master'}"
<a
ng-class=
"{'node_active': namespace.
displayControl.
currentOperateBranch != 'master'}"
ng-click=
"switchBranch(namespace.branchName)"
>
<img
src=
"img/branch.png"
>
灰度版本
...
...
apollo-portal/src/main/resources/static/views/component/namespace-panel-master-tab.html
View file @
a684730f
<!--master panel body-->
<section
class=
"master-panel-body"
ng-if=
"namespace.hasBranch
&& namespace.currentOperateBranch == 'master' ||
&& namespace.
displayControl.
currentOperateBranch == 'master' ||
!namespace.hasBranch"
>
<!--main header-->
<header
class=
"panel-heading"
>
...
...
@@ -20,6 +20,7 @@
</div>
<div
class=
"col-md-6 col-sm-6 text-right header-buttons"
>
<button
type=
"button"
class=
"btn btn-success btn-sm"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"发布配置"
ng-show=
"(namespace.hasReleasePermission || namespace.hasModifyPermission)"
...
...
@@ -54,14 +55,28 @@
ng-show=
"!namespace.hasBranch && namespace.isPropertiesFormat && namespace.hasModifyPermission"
ng-click=
"preCreateBranch(namespace)"
>
<img
src=
"img/test.png"
>
创建
灰度
灰度
</a>
<a
type=
"button"
class=
"btn btn-default btn-sm J_tableview_btn"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"您没有任何配置权限,请申请"
ng-click=
"showNoModifyPermissionDialog()"
ng-show=
"!namespace.hasModifyPermission && !namespace.hasReleasePermission"
>
申请配置权限
</a>
<div
class=
"btn-group dropdown"
>
<button
type=
"button"
class=
"btn btn-default btn-sm dropdown-toggle"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<img
src=
"img/operate.png"
>
<span
class=
"caret"
></span>
</button>
<ul
class=
"dropdown-menu"
style=
"right: 0; left: -160px;"
>
<li
ng-click=
"deleteNamespace(namespace)"
>
<a
style=
"color: red"
>
<img
src=
"img/delete.png"
>
删除Namespace
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
...
...
@@ -130,7 +145,7 @@
<button
type=
"button"
class=
"btn btn-default btn-sm"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"按Key过滤配置"
ng-show=
"namespace.viewType == 'table' && namespace.currentOperateBranch == 'master'
ng-show=
"namespace.viewType == 'table' && namespace.
displayControl.
currentOperateBranch == 'master'
&& !namespace.isLinkedNamespace"
ng-click=
"toggleItemSearchInput(namespace)"
>
<span
class=
"glyphicon glyphicon-filter"
></span>
...
...
@@ -140,7 +155,7 @@
<button
type=
"button"
class=
"btn btn-default btn-sm J_tableview_btn"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"同步各环境间配置"
ng-click=
"goToSyncPage(namespace)"
ng-show=
"namespace.viewType == 'table' && namespace.currentOperateBranch == 'master'
ng-show=
"namespace.viewType == 'table' && namespace.
displayControl.
currentOperateBranch == 'master'
&& namespace.hasModifyPermission && namespace.isPropertiesFormat"
>
<img
src=
"img/sync.png"
>
同步配置
...
...
@@ -149,7 +164,7 @@
<button
type=
"button"
class=
"btn btn-primary btn-sm"
ng-show=
"!namespace.isLinkedNamespace
&& namespace.viewType == 'table'
&& namespace.currentOperateBranch == 'master'
&& namespace.
displayControl.
currentOperateBranch == 'master'
&& namespace.hasModifyPermission"
ng-click=
"createItem(namespace)"
>
<img
src=
"img/plus.png"
>
...
...
@@ -169,7 +184,7 @@
</div>
<!--not link namespace-->
<div
ng-if=
"!namespace.isLinkedNamespace"
>
<div
class=
"search-input"
ng-show=
"namespace.showSearchInput"
>
<div
class=
"search-input"
ng-show=
"namespace.
displayControl.
showSearchInput"
>
<input
type=
"text"
class=
"form-control"
placeholder=
"输入key过滤"
ng-model=
"namespace.searchKey"
ng-change=
"searchItems(namespace)"
>
...
...
@@ -224,7 +239,7 @@
<span
ng-bind=
"config.item.key.length > 250 ? '...' :''"
></span>
<span
class=
"label label-default cursor-pointer"
ng-if=
"config.hasBranchValue"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"该配置有灰度配置,点击查看灰度的值"
ng-click=
"namespace.currentOperateBranch=namespace.branchName;namespace.branch.viewType='table'"
>
灰
</span>
ng-click=
"namespace.
displayControl.
currentOperateBranch=namespace.branchName;namespace.branch.viewType='table'"
>
灰
</span>
<span
class=
"label label-success"
ng-if=
"config.isModified && !config.oldValue"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"新增的配置"
>
新
</span>
<span
class=
"label label-info"
...
...
@@ -333,7 +348,7 @@
<span
ng-bind=
"config.item.key.length > 250 ? '...' :''"
></span>
<span
class=
"label label-default cursor-pointer"
ng-if=
"config.hasBranchValue"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"该配置有灰度配置,点击查看灰度的值"
ng-click=
"namespace.currentOperateBranch=namespace.branchName;namespace.branch.viewType='table'"
>
灰
</span>
ng-click=
"namespace.
displayControl.
currentOperateBranch=namespace.branchName;namespace.branch.viewType='table'"
>
灰
</span>
<span
class=
"label label-success"
ng-if=
"config.isModified && !config.oldValue"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"新增的配置"
>
新
</span>
<span
class=
"label label-info"
...
...
@@ -385,7 +400,8 @@
<div
class=
"row"
>
<div
class=
"padding-top-5 col-md-4 col-sm-4"
>
公共的配置
<a
href=
"/config.html?#/appid={{namespace.publicNamespace.baseInfo.appId}}&env={{env}}&cluster={{namespace.publicNamespace.baseInfo.clusterName}}"
target=
"_blank"
>
<a
href=
"/config.html?#/appid={{namespace.publicNamespace.baseInfo.appId}}&env={{env}}&cluster={{namespace.publicNamespace.baseInfo.clusterName}}"
target=
"_blank"
>
<small>
(AppId:{{namespace.publicNamespace.baseInfo.appId}},
Cluster:{{namespace.publicNamespace.baseInfo.clusterName}})
...
...
@@ -394,7 +410,8 @@
</div>
<div
class=
"col-md-4 col-sm-4 text-center"
>
<div
class=
"btn-group btn-group-sm"
role=
"group"
ng-show=
"namespace.publicNamespace.isModified"
>
<div
class=
"btn-group btn-group-sm"
role=
"group"
ng-show=
"namespace.publicNamespace.isModified"
>
<button
type=
"button"
class=
"btn btn-default"
ng-class=
"{'active':namespace.publicNamespaceViewType == 'RELEASE'
|| !namespace.publicNamespaceViewType}"
...
...
@@ -461,11 +478,13 @@
<tbody>
<tr
ng-repeat=
"config in namespace.publicNamespace.viewItems |orderBy:col:desc"
ng-if=
"config.item.key && !config.isModified && !config.isDeleted"
>
<td
width=
"15%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.item.key)"
>
<td
width=
"15%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.item.key)"
>
<span
ng-bind=
"config.item.key | limitTo: 250"
></span>
<span
ng-bind=
"config.item.key.length > 250 ? '...' :''"
></span>
</td>
<td
width=
"35%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.item.value)"
>
<td
width=
"35%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.item.value)"
>
<span
ng-bind=
"config.item.value | limitTo: 250"
></span>
<span
ng-bind=
"config.item.value.length > 250 ? '...': ''"
></span>
</td>
...
...
@@ -480,7 +499,8 @@
</td>
<td
width=
"10%"
class=
"text-center"
ng-if=
"!config.isDeleted"
>
<img
src=
"img/gray.png"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"覆盖此配置"
<img
src=
"img/gray.png"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"覆盖此配置"
ng-click=
"editItem(namespace, config.item)"
ng-show=
"namespace.hasModifyPermission && !config.covered"
>
</td>
...
...
@@ -533,7 +553,8 @@
<tbody>
<tr
ng-repeat=
"config in namespace.publicNamespace.viewItems |orderBy:col:desc"
ng-if=
"config.item.key && (config.isModified || config.isDeleted)"
>
<td
width=
"20%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.item.key)"
>
<td
width=
"20%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.item.key)"
>
<span
ng-bind=
"config.item.key | limitTo: 250"
></span>
<span
ng-bind=
"config.item.key.length > 250 ? '...' :''"
></span>
<span
class=
"label label-success"
ng-if=
"config.isModified && !config.oldValue"
...
...
@@ -544,11 +565,13 @@
<span
class=
"label label-danger"
ng-if=
"config.isDeleted"
data-tooltip=
"tooltip"
data-placement=
"bottom"
title=
"删除的配置"
>
删
</span>
</td>
<td
width=
"25%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.oldValue)"
>
<td
width=
"25%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.oldValue)"
>
<span
ng-bind=
"config.oldValue | limitTo: 250"
></span>
<span
ng-bind=
"config.oldValue.length > 250 ? '...': ''"
></span>
</td>
<td
width=
"25%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.item.value)"
>
<td
width=
"25%"
class=
"cursor-pointer"
title=
"点击查看"
ng-click=
"showText(config.item.value)"
>
<span
ng-bind=
"config.item.value | limitTo: 250"
></span>
<span
ng-bind=
"config.item.value.length > 250 ? '...': ''"
></span>
</td>
...
...
@@ -610,10 +633,11 @@
ng-repeat=
"commits in namespace.commits"
>
<div
class=
"media-body"
>
<div
class=
"row"
>
<div
class=
"col-md-6 col-sm-6"
><h3
class=
"media-heading"
ng-bind=
"commits.dataChangeCreatedBy"
></h3>
<div
class=
"col-md-6 col-sm-6"
><h3
class=
"media-heading"
ng-bind=
"commits.dataChangeCreatedBy"
></h3>
</div>
<div
class=
"col-md-6 col-sm-6 text-right"
><h5
class=
"media-heading"
ng-bind=
"commits.dataChangeCreatedTime | date: 'yyyy-MM-dd HH:mm:ss'"
></h5>
ng-bind=
"commits.dataChangeCreatedTime | date: 'yyyy-MM-dd HH:mm:ss'"
></h5>
</div>
</div>
...
...
@@ -892,4 +916,5 @@
</div>
</div>
</section>
</section>
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/ConfigServiceTest.java
View file @
a684730f
...
...
@@ -6,6 +6,7 @@ import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.core.enums.ConfigFileFormat
;
import
com.ctrip.framework.apollo.core.enums.Env
;
import
com.ctrip.framework.apollo.portal.AbstractUnitTest
;
import
com.ctrip.framework.apollo.portal.api.AdminServiceAPI
;
import
com.ctrip.framework.apollo.portal.spi.UserInfoHolder
;
import
com.ctrip.framework.apollo.portal.entity.bo.UserInfo
;
...
...
@@ -17,10 +18,8 @@ import com.ctrip.framework.apollo.portal.entity.vo.NamespaceIdentifier;
import
org.junit.Assert
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.InjectMocks
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
org.springframework.test.util.ReflectionTestUtils
;
import
java.util.Arrays
;
...
...
@@ -29,8 +28,7 @@ import java.util.List;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Mockito
.
when
;
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
ConfigServiceTest
{
public
class
ConfigServiceTest
extends
AbstractUnitTest
{
@Mock
private
AdminServiceAPI
.
NamespaceAPI
namespaceAPI
;
...
...
@@ -77,7 +75,7 @@ public class ConfigServiceTest {
try
{
configService
.
updateConfigItemByText
(
model
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Assert
.
fail
();
}
}
...
...
@@ -94,13 +92,15 @@ public class ConfigServiceTest {
}
@Test
public
void
testCompareTargetNamespaceHasNoItems
(){
ItemDTO
sourceItem1
=
new
ItemDTO
(
"a"
,
"b"
,
"comment"
,
1
);
public
void
testCompareTargetNamespaceHasNoItems
()
{
ItemDTO
sourceItem1
=
new
ItemDTO
(
"a"
,
"b"
,
"comment"
,
1
);
List
<
ItemDTO
>
sourceItems
=
Arrays
.
asList
(
sourceItem1
);
String
appId
=
"6666"
,
env
=
"LOCAL"
,
clusterName
=
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
namespaceName
=
ConfigConsts
.
NAMESPACE_APPLICATION
;
List
<
NamespaceIdentifier
>
namespaceIdentifiers
=
generateNamespaceIdentifer
(
appId
,
env
,
clusterName
,
namespaceName
);
List
<
NamespaceIdentifier
>
namespaceIdentifiers
=
generateNamespaceIdentifier
(
appId
,
env
,
clusterName
,
namespaceName
);
NamespaceDTO
namespaceDTO
=
generateNamespaceDTO
(
appId
,
clusterName
,
namespaceName
);
when
(
namespaceAPI
.
loadNamespace
(
appId
,
Env
.
valueOf
(
env
),
clusterName
,
namespaceName
)).
thenReturn
(
namespaceDTO
);
...
...
@@ -112,7 +112,7 @@ public class ConfigServiceTest {
List
<
ItemDiffs
>
itemDiffses
=
configService
.
compare
(
namespaceIdentifiers
,
sourceItems
);
assertEquals
(
1
,
itemDiffses
.
size
());
assertEquals
(
1
,
itemDiffses
.
size
());
ItemDiffs
itemDiffs
=
itemDiffses
.
get
(
0
);
ItemChangeSets
changeSets
=
itemDiffs
.
getDiffs
();
assertEquals
(
0
,
changeSets
.
getUpdateItems
().
size
());
...
...
@@ -127,21 +127,23 @@ public class ConfigServiceTest {
}
@Test
public
void
testCompare
(){
ItemDTO
sourceItem1
=
new
ItemDTO
(
"a"
,
"b"
,
"comment"
,
1
);
//not modified
ItemDTO
sourceItem2
=
new
ItemDTO
(
"newKey"
,
"c"
,
"comment"
,
2
);
//new item
ItemDTO
sourceItem3
=
new
ItemDTO
(
"c"
,
"newValue"
,
"comment"
,
3
);
// update value
ItemDTO
sourceItem4
=
new
ItemDTO
(
"d"
,
"b"
,
"newComment"
,
4
);
// update comment
public
void
testCompare
()
{
ItemDTO
sourceItem1
=
new
ItemDTO
(
"a"
,
"b"
,
"comment"
,
1
);
//not modified
ItemDTO
sourceItem2
=
new
ItemDTO
(
"newKey"
,
"c"
,
"comment"
,
2
);
//new item
ItemDTO
sourceItem3
=
new
ItemDTO
(
"c"
,
"newValue"
,
"comment"
,
3
);
// update value
ItemDTO
sourceItem4
=
new
ItemDTO
(
"d"
,
"b"
,
"newComment"
,
4
);
// update comment
List
<
ItemDTO
>
sourceItems
=
Arrays
.
asList
(
sourceItem1
,
sourceItem2
,
sourceItem3
,
sourceItem4
);
ItemDTO
targetItem1
=
new
ItemDTO
(
"a"
,
"b"
,
"comment"
,
1
);
ItemDTO
targetItem2
=
new
ItemDTO
(
"c"
,
"oldValue"
,
"comment"
,
2
);
ItemDTO
targetItem3
=
new
ItemDTO
(
"d"
,
"b"
,
"oldComment"
,
3
);
ItemDTO
targetItem1
=
new
ItemDTO
(
"a"
,
"b"
,
"comment"
,
1
);
ItemDTO
targetItem2
=
new
ItemDTO
(
"c"
,
"oldValue"
,
"comment"
,
2
);
ItemDTO
targetItem3
=
new
ItemDTO
(
"d"
,
"b"
,
"oldComment"
,
3
);
List
<
ItemDTO
>
targetItems
=
Arrays
.
asList
(
targetItem1
,
targetItem2
,
targetItem3
);
String
appId
=
"6666"
,
env
=
"LOCAL"
,
clusterName
=
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
namespaceName
=
ConfigConsts
.
NAMESPACE_APPLICATION
;
List
<
NamespaceIdentifier
>
namespaceIdentifiers
=
generateNamespaceIdentifer
(
appId
,
env
,
clusterName
,
namespaceName
);
List
<
NamespaceIdentifier
>
namespaceIdentifiers
=
generateNamespaceIdentifier
(
appId
,
env
,
clusterName
,
namespaceName
);
NamespaceDTO
namespaceDTO
=
generateNamespaceDTO
(
appId
,
clusterName
,
namespaceName
);
when
(
namespaceAPI
.
loadNamespace
(
appId
,
Env
.
valueOf
(
env
),
clusterName
,
namespaceName
)).
thenReturn
(
namespaceDTO
);
...
...
@@ -189,7 +191,7 @@ public class ConfigServiceTest {
}
private
NamespaceDTO
generateNamespaceDTO
(
String
appId
,
String
clusterName
,
String
namespaceName
){
private
NamespaceDTO
generateNamespaceDTO
(
String
appId
,
String
clusterName
,
String
namespaceName
)
{
NamespaceDTO
namespaceDTO
=
new
NamespaceDTO
();
namespaceDTO
.
setAppId
(
appId
);
namespaceDTO
.
setId
(
1
);
...
...
@@ -198,7 +200,8 @@ public class ConfigServiceTest {
return
namespaceDTO
;
}
private
List
<
NamespaceIdentifier
>
generateNamespaceIdentifer
(
String
appId
,
String
env
,
String
clusterName
,
String
namespaceName
){
private
List
<
NamespaceIdentifier
>
generateNamespaceIdentifier
(
String
appId
,
String
env
,
String
clusterName
,
String
namespaceName
)
{
NamespaceIdentifier
targetNamespace
=
new
NamespaceIdentifier
();
targetNamespace
.
setAppId
(
appId
);
targetNamespace
.
setEnv
(
env
);
...
...
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/NamespaceServiceTest.java
View file @
a684730f
...
...
@@ -4,28 +4,32 @@ import com.ctrip.framework.apollo.common.dto.ItemDTO;
import
com.ctrip.framework.apollo.common.dto.NamespaceDTO
;
import
com.ctrip.framework.apollo.common.dto.ReleaseDTO
;
import
com.ctrip.framework.apollo.common.entity.AppNamespace
;
import
com.ctrip.framework.apollo.common.exception.BadRequestException
;
import
com.ctrip.framework.apollo.core.enums.ConfigFileFormat
;
import
com.ctrip.framework.apollo.core.enums.Env
;
import
com.ctrip.framework.apollo.portal.AbstractUnitTest
;
import
com.ctrip.framework.apollo.portal.api.AdminServiceAPI
;
import
com.ctrip.framework.apollo.portal.component.txtresolver.PropertyResolver
;
import
com.ctrip.framework.apollo.portal.entity.bo.NamespaceBO
;
import
com.ctrip.framework.apollo.portal.entity.bo.UserInfo
;
import
com.ctrip.framework.apollo.portal.spi.UserInfoHolder
;
import
org.junit.Before
;
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
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
NamespaceServiceTest
{
public
class
NamespaceServiceTest
extends
AbstractUnitTest
{
@Mock
private
AdminServiceAPI
.
NamespaceAPI
namespaceAPI
;
...
...
@@ -37,10 +41,20 @@ public class NamespaceServiceTest {
private
PropertyResolver
resolver
;
@Mock
private
AppNamespaceService
appNamespaceService
;
@Mock
private
InstanceService
instanceService
;
@Mock
private
NamespaceBranchService
branchService
;
@Mock
private
UserInfoHolder
userInfoHolder
;
@InjectMocks
private
NamespaceService
namespaceService
;
private
String
testAppId
=
"6666"
;
private
String
testClusterName
=
"default"
;
private
String
testNamespaceName
=
"application"
;
private
Env
testEnv
=
Env
.
DEV
;
@Before
public
void
setup
()
{
...
...
@@ -48,23 +62,20 @@ public class NamespaceServiceTest {
@Test
public
void
testFindNamespace
()
{
String
appId
=
"6666"
;
String
clusterName
=
"default"
;
String
namespaceName
=
"application"
;
AppNamespace
applicationAppNamespace
=
mock
(
AppNamespace
.
class
);
AppNamespace
hermesAppNamespace
=
mock
(
AppNamespace
.
class
);
NamespaceDTO
application
=
new
NamespaceDTO
();
application
.
setId
(
1
);
application
.
setClusterName
(
c
lusterName
);
application
.
setAppId
(
a
ppId
);
application
.
setNamespaceName
(
n
amespaceName
);
application
.
setClusterName
(
testC
lusterName
);
application
.
setAppId
(
testA
ppId
);
application
.
setNamespaceName
(
testN
amespaceName
);
NamespaceDTO
hermes
=
new
NamespaceDTO
();
hermes
.
setId
(
2
);
hermes
.
setClusterName
(
"default"
);
hermes
.
setAppId
(
a
ppId
);
hermes
.
setAppId
(
testA
ppId
);
hermes
.
setNamespaceName
(
"hermes"
);
List
<
NamespaceDTO
>
namespaces
=
Arrays
.
asList
(
application
,
hermes
);
...
...
@@ -79,24 +90,135 @@ public class NamespaceServiceTest {
when
(
applicationAppNamespace
.
getFormat
()).
thenReturn
(
ConfigFileFormat
.
Properties
.
getValue
());
when
(
hermesAppNamespace
.
getFormat
()).
thenReturn
(
ConfigFileFormat
.
XML
.
getValue
());
when
(
appNamespaceService
.
findByAppIdAndName
(
appId
,
n
amespaceName
))
when
(
appNamespaceService
.
findByAppIdAndName
(
testAppId
,
testN
amespaceName
))
.
thenReturn
(
applicationAppNamespace
);
when
(
appNamespaceService
.
findPublicAppNamespace
(
"hermes"
)).
thenReturn
(
hermesAppNamespace
);
when
(
namespaceAPI
.
findNamespaceByCluster
(
appId
,
Env
.
DEV
,
clusterName
)).
thenReturn
(
namespaces
);
when
(
releaseService
.
loadLatestRelease
(
appId
,
Env
.
DEV
,
clusterName
,
namespaceName
)).
thenReturn
(
someRelease
);
when
(
releaseService
.
loadLatestRelease
(
appId
,
Env
.
DEV
,
clusterName
,
"hermes"
)).
thenReturn
(
someRelease
);
when
(
itemService
.
findItems
(
appId
,
Env
.
DEV
,
clusterName
,
namespaceName
)).
thenReturn
(
someItems
);
when
(
namespaceAPI
.
findNamespaceByCluster
(
testAppId
,
Env
.
DEV
,
testClusterName
)).
thenReturn
(
namespaces
);
when
(
releaseService
.
loadLatestRelease
(
testAppId
,
Env
.
DEV
,
testClusterName
,
testNamespaceName
)).
thenReturn
(
someRelease
);
when
(
releaseService
.
loadLatestRelease
(
testAppId
,
Env
.
DEV
,
testClusterName
,
"hermes"
)).
thenReturn
(
someRelease
);
when
(
itemService
.
findItems
(
testAppId
,
Env
.
DEV
,
testClusterName
,
testNamespaceName
)).
thenReturn
(
someItems
);
List
<
NamespaceBO
>
namespaceVOs
=
namespaceService
.
findNamespaceBOs
(
appId
,
Env
.
DEV
,
c
lusterName
);
List
<
NamespaceBO
>
namespaceVOs
=
namespaceService
.
findNamespaceBOs
(
testAppId
,
Env
.
DEV
,
testC
lusterName
);
assertEquals
(
2
,
namespaceVOs
.
size
());
NamespaceBO
namespaceVO
=
namespaceVOs
.
get
(
0
);
assertEquals
(
4
,
namespaceVO
.
getItems
().
size
());
assertEquals
(
"a"
,
namespaceVO
.
getItems
().
get
(
0
).
getItem
().
getKey
());
assertEquals
(
2
,
namespaceVO
.
getItemModifiedCnt
());
assertEquals
(
appId
,
namespaceVO
.
getBaseInfo
().
getAppId
());
assertEquals
(
clusterName
,
namespaceVO
.
getBaseInfo
().
getClusterName
());
assertEquals
(
namespaceName
,
namespaceVO
.
getBaseInfo
().
getNamespaceName
());
assertEquals
(
testAppId
,
namespaceVO
.
getBaseInfo
().
getAppId
());
assertEquals
(
testClusterName
,
namespaceVO
.
getBaseInfo
().
getClusterName
());
assertEquals
(
testNamespaceName
,
namespaceVO
.
getBaseInfo
().
getNamespaceName
());
}
@Test
(
expected
=
BadRequestException
.
class
)
public
void
testDeletePrivateNamespace
()
{
AppNamespace
privateNamespace
=
createAppNamespace
(
testAppId
,
testNamespaceName
,
false
);
when
(
appNamespaceService
.
findByAppIdAndName
(
testAppId
,
testNamespaceName
)).
thenReturn
(
privateNamespace
);
namespaceService
.
deleteNamespace
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
);
}
@Test
(
expected
=
BadRequestException
.
class
)
public
void
testDeleteNamespaceHasInstance
()
{
AppNamespace
publicNamespace
=
createAppNamespace
(
testAppId
,
testNamespaceName
,
true
);
when
(
appNamespaceService
.
findByAppIdAndName
(
testAppId
,
testNamespaceName
)).
thenReturn
(
publicNamespace
);
when
(
instanceService
.
getInstanceCountByNamepsace
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
))
.
thenReturn
(
10
);
namespaceService
.
deleteNamespace
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
);
}
@Test
(
expected
=
BadRequestException
.
class
)
public
void
testDeleteNamespaceBranchHasInstance
()
{
AppNamespace
publicNamespace
=
createAppNamespace
(
testAppId
,
testNamespaceName
,
true
);
String
branchName
=
"branch"
;
NamespaceDTO
branch
=
createNamespace
(
testAppId
,
branchName
,
testNamespaceName
);
when
(
appNamespaceService
.
findByAppIdAndName
(
testAppId
,
testNamespaceName
)).
thenReturn
(
publicNamespace
);
when
(
instanceService
.
getInstanceCountByNamepsace
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
))
.
thenReturn
(
0
);
when
(
branchService
.
findBranchBaseInfo
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
)).
thenReturn
(
branch
);
when
(
instanceService
.
getInstanceCountByNamepsace
(
testAppId
,
testEnv
,
branchName
,
testNamespaceName
)).
thenReturn
(
10
);
namespaceService
.
deleteNamespace
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
);
}
@Test
(
expected
=
BadRequestException
.
class
)
public
void
testDeleteNamespaceWithAssociatedNamespace
()
{
AppNamespace
publicNamespace
=
createAppNamespace
(
testAppId
,
testNamespaceName
,
true
);
String
branchName
=
"branch"
;
NamespaceDTO
branch
=
createNamespace
(
testAppId
,
branchName
,
testNamespaceName
);
when
(
appNamespaceService
.
findByAppIdAndName
(
testAppId
,
testNamespaceName
)).
thenReturn
(
publicNamespace
);
when
(
instanceService
.
getInstanceCountByNamepsace
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
))
.
thenReturn
(
0
);
when
(
branchService
.
findBranchBaseInfo
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
)).
thenReturn
(
branch
);
when
(
instanceService
.
getInstanceCountByNamepsace
(
testAppId
,
testEnv
,
branchName
,
testNamespaceName
)).
thenReturn
(
0
);
when
(
appNamespaceService
.
findPublicAppNamespace
(
testNamespaceName
)).
thenReturn
(
publicNamespace
);
when
(
namespaceAPI
.
countPublicAppNamespaceAssociatedNamespaces
(
testEnv
,
testNamespaceName
)).
thenReturn
(
10
);
namespaceService
.
deleteNamespace
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
);
}
@Test
public
void
testDeleteEmptyNamespace
()
{
String
branchName
=
"branch"
;
String
operator
=
"user"
;
AppNamespace
publicNamespace
=
createAppNamespace
(
testAppId
,
testNamespaceName
,
true
);
NamespaceDTO
branch
=
createNamespace
(
testAppId
,
branchName
,
testNamespaceName
);
when
(
appNamespaceService
.
findByAppIdAndName
(
testAppId
,
testNamespaceName
)).
thenReturn
(
publicNamespace
);
when
(
instanceService
.
getInstanceCountByNamepsace
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
))
.
thenReturn
(
0
);
when
(
branchService
.
findBranchBaseInfo
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
)).
thenReturn
(
branch
);
when
(
instanceService
.
getInstanceCountByNamepsace
(
testAppId
,
testEnv
,
branchName
,
testNamespaceName
)).
thenReturn
(
0
);
when
(
appNamespaceService
.
findPublicAppNamespace
(
testNamespaceName
)).
thenReturn
(
publicNamespace
);
NamespaceDTO
namespace
=
createNamespace
(
testAppId
,
testClusterName
,
testNamespaceName
);
when
(
namespaceAPI
.
getPublicAppNamespaceAllNamespaces
(
testEnv
,
testNamespaceName
,
0
,
10
)).
thenReturn
(
Collections
.
singletonList
(
namespace
));
when
(
userInfoHolder
.
getUser
()).
thenReturn
(
createUser
(
operator
));
namespaceService
.
deleteNamespace
(
testAppId
,
testEnv
,
testClusterName
,
testNamespaceName
);
verify
(
namespaceAPI
,
times
(
1
)).
deleteNamespace
(
testEnv
,
testAppId
,
testClusterName
,
testNamespaceName
,
operator
);
}
private
AppNamespace
createAppNamespace
(
String
appId
,
String
name
,
boolean
isPublic
)
{
AppNamespace
instance
=
new
AppNamespace
();
instance
.
setAppId
(
appId
);
instance
.
setName
(
name
);
instance
.
setPublic
(
isPublic
);
return
instance
;
}
private
NamespaceDTO
createNamespace
(
String
appId
,
String
clusterName
,
String
namespaceName
)
{
NamespaceDTO
instance
=
new
NamespaceDTO
();
instance
.
setAppId
(
appId
);
instance
.
setClusterName
(
clusterName
);
instance
.
setNamespaceName
(
namespaceName
);
return
instance
;
}
private
UserInfo
createUser
(
String
userId
)
{
UserInfo
instance
=
new
UserInfo
();
instance
.
setUserId
(
userId
);
return
instance
;
}
}
scripts/sql/apolloconfigdb.sql
View file @
a684730f
...
...
@@ -243,7 +243,8 @@ CREATE TABLE `Namespace` (
`DataChange_LastTime`
timestamp
NULL
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
COMMENT
'最后修改时间'
,
PRIMARY
KEY
(
`Id`
),
KEY
`AppId_ClusterName_NamespaceName`
(
`AppId`
(
191
),
`ClusterName`
(
191
),
`NamespaceName`
(
191
)),
KEY
`DataChange_LastTime`
(
`DataChange_LastTime`
)
KEY
`DataChange_LastTime`
(
`DataChange_LastTime`
),
KEY
`IX_NamespaceName`
(
`NamespaceName`
(
191
))
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COMMENT
=
'命名空间'
;
...
...
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