Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wrr-cat
apollo
提交
adb46345
apollo
项目概览
wrr-cat
/
apollo
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
apollo
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
adb46345
编写于
9月 16, 2018
作者:
J
Jason Song
提交者:
GitHub
9月 16, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1476 from nobodyiam/allow-public-namespace-with-no-org-prefix
allow public namespaces created with no org prefix
上级
9e3aec54
b949afac
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
111 addition
and
22 deletion
+111
-22
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java
...amework/apollo/portal/controller/NamespaceController.java
+6
-4
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/AppNamespaceRepository.java
...work/apollo/portal/repository/AppNamespaceRepository.java
+1
-1
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppNamespaceService.java
.../framework/apollo/portal/service/AppNamespaceService.java
+50
-8
apollo-portal/src/main/resources/static/namespace.html
apollo-portal/src/main/resources/static/namespace.html
+20
-4
apollo-portal/src/main/resources/static/scripts/controller/NamespaceController.js
...esources/static/scripts/controller/NamespaceController.js
+4
-1
apollo-portal/src/main/resources/static/scripts/services/NamespaceService.js
...ain/resources/static/scripts/services/NamespaceService.js
+5
-4
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/AppNamespaceServiceTest.java
...mework/apollo/portal/service/AppNamespaceServiceTest.java
+25
-0
未找到文件。
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java
浏览文件 @
adb46345
...
...
@@ -161,16 +161,18 @@ public class NamespaceController {
@PreAuthorize
(
value
=
"@permissionValidator.hasCreateAppNamespacePermission(#appId, #appNamespace)"
)
@RequestMapping
(
value
=
"/apps/{appId}/appnamespaces"
,
method
=
RequestMethod
.
POST
)
public
AppNamespace
createAppNamespace
(
@PathVariable
String
appId
,
@RequestBody
AppNamespace
appNamespace
)
{
public
AppNamespace
createAppNamespace
(
@PathVariable
String
appId
,
@RequestParam
(
defaultValue
=
"true"
)
boolean
appendNamespacePrefix
,
@RequestBody
AppNamespace
appNamespace
)
{
RequestPrecondition
.
checkArgumentsNotEmpty
(
appNamespace
.
getAppId
(),
appNamespace
.
getName
());
if
(!
InputValidator
.
isValidAppNamespace
(
appNamespace
.
getName
()))
{
throw
new
BadRequestException
(
String
.
format
(
"Namespace格式错误: %s"
,
InputValidator
.
INVALID_CLUSTER_NAMESPACE_MESSAGE
+
" & "
+
InputValidator
.
INVALID_NAMESPACE_NAMESPACE_MESSAGE
));
InputValidator
.
INVALID_CLUSTER_NAMESPACE_MESSAGE
+
" & "
+
InputValidator
.
INVALID_NAMESPACE_NAMESPACE_MESSAGE
));
}
AppNamespace
createdAppNamespace
=
appNamespaceService
.
createAppNamespaceInLocal
(
appNamespace
);
AppNamespace
createdAppNamespace
=
appNamespaceService
.
createAppNamespaceInLocal
(
appNamespace
,
appendNamespacePrefix
);
if
(
portalConfig
.
canAppAdminCreatePrivateNamespace
()
||
createdAppNamespace
.
isPublic
())
{
assignNamespaceRoleToOperator
(
appId
,
appNamespace
.
getName
());
...
...
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/AppNamespaceRepository.java
浏览文件 @
adb46345
...
...
@@ -12,7 +12,7 @@ public interface AppNamespaceRepository extends PagingAndSortingRepository<AppNa
AppNamespace
findByName
(
String
namespaceName
);
AppNamespace
findByNameAndIsPublic
(
String
namespaceName
,
boolean
isPublic
);
List
<
AppNamespace
>
findByNameAndIsPublic
(
String
namespaceName
,
boolean
isPublic
);
List
<
AppNamespace
>
findByIsPublicTrue
();
...
...
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppNamespaceService.java
浏览文件 @
adb46345
...
...
@@ -9,16 +9,23 @@ import com.ctrip.framework.apollo.core.utils.StringUtils;
import
com.ctrip.framework.apollo.portal.repository.AppNamespaceRepository
;
import
com.ctrip.framework.apollo.portal.spi.UserInfoHolder
;
import
com.google.common.base.Joiner
;
import
com.google.common.collect.Sets
;
import
java.util.Set
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.List
;
import
java.util.Objects
;
import
org.springframework.util.CollectionUtils
;
@Service
public
class
AppNamespaceService
{
private
static
final
int
PRIVATE_APP_NAMESPACE_NOTIFICATION_COUNT
=
5
;
private
static
final
Joiner
APP_NAMESPACE_JOINER
=
Joiner
.
on
(
","
).
skipNulls
();
@Autowired
private
UserInfoHolder
userInfoHolder
;
@Autowired
...
...
@@ -38,7 +45,17 @@ public class AppNamespaceService {
}
public
AppNamespace
findPublicAppNamespace
(
String
namespaceName
)
{
return
appNamespaceRepository
.
findByNameAndIsPublic
(
namespaceName
,
true
);
List
<
AppNamespace
>
appNamespaces
=
appNamespaceRepository
.
findByNameAndIsPublic
(
namespaceName
,
true
);
if
(
CollectionUtils
.
isEmpty
(
appNamespaces
))
{
return
null
;
}
return
appNamespaces
.
get
(
0
);
}
private
List
<
AppNamespace
>
findAllPrivateAppNamespaces
(
String
namespaceName
)
{
return
appNamespaceRepository
.
findByNameAndIsPublic
(
namespaceName
,
false
);
}
public
AppNamespace
findByAppIdAndName
(
String
appId
,
String
namespaceName
)
{
...
...
@@ -69,8 +86,12 @@ public class AppNamespaceService {
return
Objects
.
isNull
(
appNamespaceRepository
.
findByAppIdAndName
(
appId
,
namespaceName
));
}
@Transactional
public
AppNamespace
createAppNamespaceInLocal
(
AppNamespace
appNamespace
)
{
return
createAppNamespaceInLocal
(
appNamespace
,
true
);
}
@Transactional
public
AppNamespace
createAppNamespaceInLocal
(
AppNamespace
appNamespace
,
boolean
appendNamespacePrefix
)
{
String
appId
=
appNamespace
.
getAppId
();
//add app org id as prefix
...
...
@@ -82,7 +103,7 @@ public class AppNamespaceService {
StringBuilder
appNamespaceName
=
new
StringBuilder
();
//add prefix postfix
appNamespaceName
.
append
(
appNamespace
.
isPublic
()
?
app
.
getOrgId
()
+
"."
:
""
)
.
append
(
appNamespace
.
isPublic
()
&&
appendNamespacePrefix
?
app
.
getOrgId
()
+
"."
:
""
)
.
append
(
appNamespace
.
getName
())
.
append
(
appNamespace
.
formatAsEnum
()
==
ConfigFileFormat
.
Properties
?
""
:
"."
+
appNamespace
.
getFormat
());
appNamespace
.
setName
(
appNamespaceName
.
toString
());
...
...
@@ -103,12 +124,9 @@ public class AppNamespaceService {
appNamespace
.
setDataChangeLastModifiedBy
(
operator
);
//
unique
check
//
globally uniqueness
check
if
(
appNamespace
.
isPublic
())
{
AppNamespace
publicAppNamespace
=
findPublicAppNamespace
(
appNamespace
.
getName
());
if
(
publicAppNamespace
!=
null
)
{
throw
new
BadRequestException
(
"Public AppNamespace "
+
appNamespace
.
getName
()
+
" already exists in appId: "
+
publicAppNamespace
.
getAppId
()
+
"!"
);
}
checkAppNamespaceGlobalUniqueness
(
appNamespace
);
}
if
(!
appNamespace
.
isPublic
()
&&
...
...
@@ -124,6 +142,30 @@ public class AppNamespaceService {
return
createdAppNamespace
;
}
private
void
checkAppNamespaceGlobalUniqueness
(
AppNamespace
appNamespace
)
{
AppNamespace
publicAppNamespace
=
findPublicAppNamespace
(
appNamespace
.
getName
());
if
(
publicAppNamespace
!=
null
)
{
throw
new
BadRequestException
(
"Public AppNamespace "
+
appNamespace
.
getName
()
+
" already exists in appId: "
+
publicAppNamespace
.
getAppId
()
+
"!"
);
}
List
<
AppNamespace
>
privateAppNamespaces
=
findAllPrivateAppNamespaces
(
appNamespace
.
getName
());
if
(!
CollectionUtils
.
isEmpty
(
privateAppNamespaces
))
{
Set
<
String
>
appIds
=
Sets
.
newHashSet
();
for
(
AppNamespace
ans
:
privateAppNamespaces
)
{
appIds
.
add
(
ans
.
getAppId
());
if
(
appIds
.
size
()
==
PRIVATE_APP_NAMESPACE_NOTIFICATION_COUNT
)
{
break
;
}
}
throw
new
BadRequestException
(
"Public AppNamespace "
+
appNamespace
.
getName
()
+
" already exists as private AppNamespace in appId: "
+
APP_NAMESPACE_JOINER
.
join
(
appIds
)
+
", etc. Please select another name!"
);
}
}
@Transactional
public
AppNamespace
deleteAppNamespace
(
String
appId
,
String
namespaceName
)
{
AppNamespace
appNamespace
=
appNamespaceRepository
.
findByAppIdAndName
(
appId
,
namespaceName
);
...
...
apollo-portal/src/main/resources/static/namespace.html
浏览文件 @
adb46345
...
...
@@ -95,9 +95,9 @@
<label
class=
"col-sm-3 control-label"
>
<apollorequiredfield></apollorequiredfield>
名称
</label>
<div
class=
"col-sm-
4
"
valdr-form-group
>
<div
ng-class=
"{'input-group':appNamespace.isPublic}"
>
<span
class=
"input-group-addon"
ng-show=
"appNamespace.isPublic"
<div
class=
"col-sm-
5
"
valdr-form-group
>
<div
ng-class=
"{'input-group':appNamespace.isPublic
&& appendNamespacePrefix
}"
>
<span
class=
"input-group-addon"
ng-show=
"appNamespace.isPublic
&& appendNamespacePrefix
"
ng-bind=
"appBaseInfo.namespacePrefix"
></span>
<input
type=
"text"
name=
"namespaceName"
class=
"form-control"
ng-model=
"appNamespace.name"
>
...
...
@@ -116,9 +116,25 @@
</div>
<span
ng-show=
"appNamespace.isPublic"
ng-bind=
"concatNamespace()"
<span
ng-show=
"appNamespace.isPublic
&& appendNamespacePrefix
"
ng-bind=
"concatNamespace()"
style=
"line-height: 34px;"
></span>
</div>
<div
class=
"form-group"
ng-show=
"type == 'create' && appNamespace.isPublic"
>
<label
class=
"col-sm-3 control-label"
>
自动添加部门前缀
</label>
<div
class=
"col-sm-6"
valdr-form-group
>
<div>
<label
class=
"checkbox-inline"
>
<input
type=
"checkbox"
ng-model=
"appendNamespacePrefix"
/>
{{appBaseInfo.namespacePrefix}}
</label>
</div>
<small>
(公共Namespace的名称需要全局唯一,添加部门前缀有助于保证全局唯一性)
</small>
</div>
</div>
<div
class=
"form-group"
ng-show=
"type == 'create' && (pageSetting.canAppAdminCreatePrivateNamespace || hasRootPermission)"
>
<label
class=
"col-sm-3 control-label"
>
<apollorequiredfield></apollorequiredfield>
...
...
apollo-portal/src/main/resources/static/scripts/controller/NamespaceController.js
浏览文件 @
adb46345
...
...
@@ -11,6 +11,7 @@ namespace_module.controller("LinkNamespaceController",
$scope
.
step
=
1
;
$scope
.
submitBtnDisabled
=
false
;
$scope
.
appendNamespacePrefix
=
true
;
PermissionService
.
has_root_permission
().
then
(
function
(
result
)
{
$scope
.
hasRootPermission
=
result
.
hasPermission
;
...
...
@@ -125,7 +126,9 @@ namespace_module.controller("LinkNamespaceController",
}
$scope
.
submitBtnDisabled
=
true
;
NamespaceService
.
createAppNamespace
(
$scope
.
appId
,
$scope
.
appNamespace
).
then
(
//only append namespace prefix for public app namespace
var
appendNamespacePrefix
=
$scope
.
appNamespace
.
isPublic
?
$scope
.
appendNamespacePrefix
:
false
;
NamespaceService
.
createAppNamespace
(
$scope
.
appId
,
$scope
.
appNamespace
,
appendNamespacePrefix
).
then
(
function
(
result
)
{
$scope
.
step
=
2
;
setTimeout
(
function
()
{
...
...
apollo-portal/src/main/resources/static/scripts/services/NamespaceService.js
浏览文件 @
adb46345
...
...
@@ -12,7 +12,7 @@ appService.service("NamespaceService", ['$resource', '$q', function ($resource,
},
createAppNamespace
:
{
method
:
'
POST
'
,
url
:
'
/apps/:appId/appnamespaces
'
,
url
:
'
/apps/:appId/appnamespaces
?appendNamespacePrefix=:appendNamespacePrefix
'
,
isArray
:
false
},
getNamespacePublishInfo
:
{
...
...
@@ -60,11 +60,12 @@ appService.service("NamespaceService", ['$resource', '$q', function ($resource,
return
d
.
promise
;
}
function
createAppNamespace
(
appId
,
appnamespace
)
{
function
createAppNamespace
(
appId
,
appnamespace
,
appendNamespacePrefix
)
{
var
d
=
$q
.
defer
();
namespace_source
.
createAppNamespace
({
appId
:
appId
},
appnamespace
,
function
(
result
)
{
appId
:
appId
,
appendNamespacePrefix
:
appendNamespacePrefix
},
appnamespace
,
function
(
result
)
{
d
.
resolve
(
result
);
},
function
(
result
)
{
d
.
reject
(
result
);
...
...
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/AppNamespaceServiceTest.java
浏览文件 @
adb46345
...
...
@@ -76,6 +76,31 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
appNamespaceService
.
createAppNamespaceInLocal
(
appNamespace
);
}
@Test
@Sql
(
scripts
=
"/sql/appnamespaceservice/init-appnamespace.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
BEFORE_TEST_METHOD
)
@Sql
(
scripts
=
"/sql/cleanup.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
AFTER_TEST_METHOD
)
public
void
testCreatePublicAppNamespaceNotExistedWithNoAppendnamespacePrefix
()
{
AppNamespace
appNamespace
=
assmbleBaseAppNamespace
();
appNamespace
.
setPublic
(
true
);
appNamespace
.
setName
(
"old"
);
AppNamespace
createdAppNamespace
=
appNamespaceService
.
createAppNamespaceInLocal
(
appNamespace
,
false
);
Assert
.
assertNotNull
(
createdAppNamespace
);
Assert
.
assertEquals
(
appNamespace
.
getName
(),
createdAppNamespace
.
getName
());
}
@Test
(
expected
=
BadRequestException
.
class
)
@Sql
(
scripts
=
"/sql/appnamespaceservice/init-appnamespace.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
BEFORE_TEST_METHOD
)
@Sql
(
scripts
=
"/sql/cleanup.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
AFTER_TEST_METHOD
)
public
void
testCreatePublicAppNamespaceExistedWithNoAppendnamespacePrefix
()
{
AppNamespace
appNamespace
=
assmbleBaseAppNamespace
();
appNamespace
.
setPublic
(
true
);
appNamespace
.
setName
(
"datasource"
);
appNamespaceService
.
createAppNamespaceInLocal
(
appNamespace
,
false
);
}
@Test
@Sql
(
scripts
=
"/sql/appnamespaceservice/init-appnamespace.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
BEFORE_TEST_METHOD
)
@Sql
(
scripts
=
"/sql/cleanup.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
AFTER_TEST_METHOD
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录