Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
apollo
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
openSource
apollo
Commits
46931840
Commit
46931840
authored
May 03, 2016
by
lepdou
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #162 from lepdou/lepdou_master
sync items
parents
8e6ac7c1
e8150525
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
737 additions
and
79 deletions
+737
-79
ConfigController.java
.../com/ctrip/apollo/portal/controller/ConfigController.java
+27
-0
ItemDiffs.java
...c/main/java/com/ctrip/apollo/portal/entity/ItemDiffs.java
+27
-0
NamespaceIdentifer.java
...va/com/ctrip/apollo/portal/entity/NamespaceIdentifer.java
+50
-0
SimpleMsg.java
...c/main/java/com/ctrip/apollo/portal/entity/SimpleMsg.java
+0
-18
NamespaceReleaseModel.java
...trip/apollo/portal/entity/form/NamespaceReleaseModel.java
+1
-1
NamespaceSyncModel.java
...m/ctrip/apollo/portal/entity/form/NamespaceSyncModel.java
+43
-0
NamespaceTextModel.java
...m/ctrip/apollo/portal/entity/form/NamespaceTextModel.java
+1
-1
Verifiable.java
.../java/com/ctrip/apollo/portal/entity/form/Verifiable.java
+1
-1
ConfigService.java
...n/java/com/ctrip/apollo/portal/service/ConfigService.java
+84
-0
application.yml
apollo-portal/src/main/resources/application.yml
+1
-1
sync-error.png
apollo-portal/src/main/resources/static/img/sync-error.png
+0
-0
sync-succ.png
apollo-portal/src/main/resources/static/img/sync-succ.png
+0
-0
sync.png
apollo-portal/src/main/resources/static/img/sync.png
+0
-0
index.html
apollo-portal/src/main/resources/static/index.html
+4
-0
AppUtils.js
apollo-portal/src/main/resources/static/scripts/AppUtils.js
+23
-1
PageCommon.js
...lo-portal/src/main/resources/static/scripts/PageCommon.js
+12
-0
app.js
apollo-portal/src/main/resources/static/scripts/app.js
+2
-0
AppConfigController.js
...rces/static/scripts/controller/app/AppConfigController.js
+18
-14
SyncConfigController.js
...ces/static/scripts/controller/app/SyncConfigController.js
+76
-0
ConfigService.js
...c/main/resources/static/scripts/services/ConfigService.js
+21
-2
common-style.css
...-portal/src/main/resources/static/styles/common-style.css
+4
-0
app.html
apollo-portal/src/main/resources/static/views/app.html
+33
-40
sync.html
apollo-portal/src/main/resources/static/views/sync.html
+200
-0
ConfigServiceTest.java
.../test/java/com/ctrip/apollo/portal/ConfigServiceTest.java
+109
-0
No files found.
apollo-portal/src/main/java/com/ctrip/apollo/portal/controller/ConfigController.java
View file @
46931840
package
com
.
ctrip
.
apollo
.
portal
.
controller
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.apollo.core.dto.ReleaseDTO
;
import
com.ctrip.apollo.core.exception.BadRequestException
;
import
com.ctrip.apollo.core.utils.StringUtils
;
import
com.ctrip.apollo.portal.entity.ItemDiffs
;
import
com.ctrip.apollo.portal.entity.form.NamespaceSyncModel
;
import
com.ctrip.apollo.portal.entity.form.NamespaceTextModel
;
import
com.ctrip.apollo.portal.entity.NamespaceVO
;
import
com.ctrip.apollo.portal.entity.form.NamespaceReleaseModel
;
...
...
@@ -78,4 +81,28 @@ public class ConfigController {
}
@RequestMapping
(
value
=
"/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items"
)
public
List
<
ItemDTO
>
findItems
(
@PathVariable
String
appId
,
@PathVariable
String
env
,
@PathVariable
String
clusterName
,
@PathVariable
String
namespaceName
){
if
(
StringUtils
.
isContainEmpty
(
appId
,
env
,
clusterName
,
namespaceName
)){
throw
new
BadRequestException
(
"appid,env,cluster name,namespace name can not be null"
);
}
return
configService
.
findItems
(
appId
,
Env
.
valueOf
(
env
),
clusterName
,
namespaceName
);
}
@RequestMapping
(
value
=
"/namespaces/{namespaceName}/diff"
,
method
=
RequestMethod
.
POST
,
consumes
=
{
"application/json"
})
public
List
<
ItemDiffs
>
diff
(
@RequestBody
NamespaceSyncModel
model
){
if
(
model
==
null
){
throw
new
BadRequestException
(
"request payload shoud not be null"
);
}
if
(
model
.
isInvalid
())
{
throw
new
BadRequestException
(
"request model is invalid"
);
}
return
configService
.
compare
(
model
.
getSyncItems
(),
model
.
getSyncToNamespaces
());
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/entity/ItemDiffs.java
0 → 100644
View file @
46931840
package
com
.
ctrip
.
apollo
.
portal
.
entity
;
import
com.ctrip.apollo.core.dto.ItemChangeSets
;
public
class
ItemDiffs
{
private
NamespaceIdentifer
namespace
;
private
ItemChangeSets
diffs
;
public
ItemDiffs
(
NamespaceIdentifer
namespace
){
this
.
namespace
=
namespace
;
}
public
NamespaceIdentifer
getNamespace
()
{
return
namespace
;
}
public
void
setNamespace
(
NamespaceIdentifer
namespace
)
{
this
.
namespace
=
namespace
;
}
public
ItemChangeSets
getDiffs
()
{
return
diffs
;
}
public
void
setDiffs
(
ItemChangeSets
diffs
)
{
this
.
diffs
=
diffs
;
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/entity/NamespaceIdentifer.java
0 → 100644
View file @
46931840
package
com
.
ctrip
.
apollo
.
portal
.
entity
;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.apollo.core.utils.StringUtils
;
import
com.ctrip.apollo.portal.entity.form.Verifiable
;
public
class
NamespaceIdentifer
implements
Verifiable
{
private
String
appId
;
private
String
env
;
private
String
clusterName
;
private
String
namespaceName
;
public
String
getAppId
()
{
return
appId
;
}
public
void
setAppId
(
String
appId
)
{
this
.
appId
=
appId
;
}
public
Env
getEnv
()
{
return
Env
.
valueOf
(
env
);
}
public
void
setEnv
(
String
env
)
{
this
.
env
=
env
;
}
public
String
getClusterName
()
{
return
clusterName
;
}
public
void
setClusterName
(
String
clusterName
)
{
this
.
clusterName
=
clusterName
;
}
public
String
getNamespaceName
()
{
return
namespaceName
;
}
public
void
setNamespaceName
(
String
namespaceName
)
{
this
.
namespaceName
=
namespaceName
;
}
@Override
public
boolean
isInvalid
()
{
return
StringUtils
.
isContainEmpty
(
env
,
clusterName
,
namespaceName
);
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/entity/SimpleMsg.java
deleted
100644 → 0
View file @
8e6ac7c1
package
com
.
ctrip
.
apollo
.
portal
.
entity
;
public
class
SimpleMsg
{
private
String
msg
;
public
SimpleMsg
(
String
msg
){
this
.
msg
=
msg
;
}
public
String
getMsg
()
{
return
msg
;
}
public
void
setMsg
(
String
msg
)
{
this
.
msg
=
msg
;
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/entity/form/NamespaceReleaseModel.java
View file @
46931840
...
...
@@ -4,7 +4,7 @@ package com.ctrip.apollo.portal.entity.form;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.apollo.core.utils.StringUtils
;
public
class
NamespaceReleaseModel
implements
FormModel
{
public
class
NamespaceReleaseModel
implements
Verifiable
{
private
String
appId
;
private
String
env
;
...
...
apollo-portal/src/main/java/com/ctrip/apollo/portal/entity/form/NamespaceSyncModel.java
0 → 100644
View file @
46931840
package
com
.
ctrip
.
apollo
.
portal
.
entity
.
form
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.portal.entity.NamespaceIdentifer
;
import
org.springframework.util.CollectionUtils
;
import
java.util.List
;
public
class
NamespaceSyncModel
implements
Verifiable
{
private
List
<
NamespaceIdentifer
>
syncToNamespaces
;
private
List
<
ItemDTO
>
syncItems
;
@Override
public
boolean
isInvalid
()
{
if
(
CollectionUtils
.
isEmpty
(
syncToNamespaces
)
||
CollectionUtils
.
isEmpty
(
syncItems
)){
return
true
;
}
for
(
NamespaceIdentifer
namespaceIdentifer:
syncToNamespaces
){
if
(
namespaceIdentifer
.
isInvalid
()){
return
true
;
}
}
return
false
;
}
public
List
<
NamespaceIdentifer
>
getSyncToNamespaces
()
{
return
syncToNamespaces
;
}
public
void
setSyncToNamespaces
(
List
<
NamespaceIdentifer
>
syncToNamespaces
)
{
this
.
syncToNamespaces
=
syncToNamespaces
;
}
public
List
<
ItemDTO
>
getSyncItems
()
{
return
syncItems
;
}
public
void
setSyncItems
(
List
<
ItemDTO
>
syncItems
)
{
this
.
syncItems
=
syncItems
;
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/entity/form/NamespaceTextModel.java
View file @
46931840
...
...
@@ -4,7 +4,7 @@ package com.ctrip.apollo.portal.entity.form;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.apollo.core.utils.StringUtils
;
public
class
NamespaceTextModel
implements
FormModel
{
public
class
NamespaceTextModel
implements
Verifiable
{
private
String
appId
;
private
String
env
;
...
...
apollo-portal/src/main/java/com/ctrip/apollo/portal/entity/form/
FormModel
.java
→
apollo-portal/src/main/java/com/ctrip/apollo/portal/entity/form/
Verifiable
.java
View file @
46931840
package
com
.
ctrip
.
apollo
.
portal
.
entity
.
form
;
public
interface
FormModel
{
public
interface
Verifiable
{
boolean
isInvalid
();
...
...
apollo-portal/src/main/java/com/ctrip/apollo/portal/service/ConfigService.java
View file @
46931840
...
...
@@ -7,17 +7,23 @@ import org.slf4j.LoggerFactory;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.web.client.HttpClientErrorException
;
import
com.ctrip.apollo.common.utils.BeanUtils
;
import
com.ctrip.apollo.common.utils.ExceptionUtils
;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.apollo.core.dto.ItemChangeSets
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.core.dto.NamespaceDTO
;
import
com.ctrip.apollo.core.dto.ReleaseDTO
;
import
com.ctrip.apollo.core.exception.BadRequestException
;
import
com.ctrip.apollo.core.exception.NotFoundException
;
import
com.ctrip.apollo.core.exception.ServiceException
;
import
com.ctrip.apollo.core.utils.StringUtils
;
import
com.ctrip.apollo.portal.api.AdminServiceAPI
;
import
com.ctrip.apollo.portal.entity.ItemDiffs
;
import
com.ctrip.apollo.portal.entity.NamespaceIdentifer
;
import
com.ctrip.apollo.portal.entity.form.NamespaceTextModel
;
import
com.ctrip.apollo.portal.entity.NamespaceVO
;
import
com.ctrip.apollo.portal.entity.form.NamespaceReleaseModel
;
...
...
@@ -172,4 +178,82 @@ public class ConfigService {
return
releaseAPI
.
release
(
model
.
getAppId
(),
model
.
getEnv
(),
model
.
getClusterName
(),
model
.
getNamespaceName
(),
model
.
getReleaseBy
(),
model
.
getReleaseComment
());
}
public
List
<
ItemDTO
>
findItems
(
String
appId
,
Env
env
,
String
clusterName
,
String
namespaceName
){
return
itemAPI
.
findItems
(
appId
,
env
,
clusterName
,
namespaceName
);
}
public
List
<
ItemDiffs
>
compare
(
List
<
ItemDTO
>
sourceItems
,
List
<
NamespaceIdentifer
>
comparedNamespaces
){
List
<
ItemDiffs
>
result
=
new
LinkedList
<>();
String
appId
,
clusterName
,
namespaceName
;
Env
env
;
for
(
NamespaceIdentifer
namespace:
comparedNamespaces
){
appId
=
namespace
.
getAppId
();
clusterName
=
namespace
.
getClusterName
();
namespaceName
=
namespace
.
getNamespaceName
();
env
=
namespace
.
getEnv
();
NamespaceDTO
namespaceDTO
=
null
;
try
{
namespaceDTO
=
namespaceAPI
.
loadNamespace
(
appId
,
env
,
clusterName
,
namespaceName
);
}
catch
(
NotFoundException
e
){
logger
.
warn
(
"namespace not exist. appId:{}, env:{}, clusterName:{}, namespaceName:{}"
,
appId
,
env
,
clusterName
,
namespaceName
);
throw
new
BadRequestException
(
String
.
format
(
"namespace not exist. appId:%s, env:%s, clusterName:%s, namespaceName:%s"
,
appId
,
env
,
clusterName
,
namespaceName
));
}
ItemDiffs
itemDiffs
=
new
ItemDiffs
(
namespace
);
ItemChangeSets
changeSets
=
new
ItemChangeSets
();
itemDiffs
.
setDiffs
(
changeSets
);
List
<
ItemDTO
>
targetItems
=
itemAPI
.
findItems
(
namespace
.
getAppId
(),
namespace
.
getEnv
(),
namespace
.
getClusterName
(),
namespace
.
getNamespaceName
());
long
namespaceId
=
namespaceDTO
.
getId
();
if
(
CollectionUtils
.
isEmpty
(
targetItems
)){
//all source items is added
int
lineNum
=
1
;
for
(
ItemDTO
sourceItem:
sourceItems
){
changeSets
.
addCreateItem
(
buildItem
(
namespaceId
,
lineNum
++,
sourceItem
));
}
}
else
{
Map
<
String
,
ItemDTO
>
keyMapItem
=
BeanUtils
.
mapByKey
(
"key"
,
targetItems
);
String
key
,
sourceValue
,
sourceComment
;
ItemDTO
targetItem
=
null
;
int
maxLineNum
=
targetItems
.
size
();
//append to last
for
(
ItemDTO
sourceItem:
sourceItems
){
key
=
sourceItem
.
getKey
();
sourceValue
=
sourceItem
.
getValue
();
sourceComment
=
sourceItem
.
getComment
();
targetItem
=
keyMapItem
.
get
(
key
);
if
(
targetItem
==
null
)
{
//added items
changeSets
.
addCreateItem
(
buildItem
(
namespaceId
,
++
maxLineNum
,
sourceItem
));
}
else
if
(!
sourceValue
.
equals
(
targetItem
.
getValue
())
||
!
sourceComment
.
equals
(
targetItem
.
getComment
())){
//modified items
targetItem
.
setValue
(
sourceValue
);
targetItem
.
setComment
(
sourceComment
);
changeSets
.
addUpdateItem
(
targetItem
);
}
}
}
result
.
add
(
itemDiffs
);
}
return
result
;
}
private
ItemDTO
buildItem
(
long
namespaceId
,
int
lineNum
,
ItemDTO
sourceItem
){
ItemDTO
createdItem
=
new
ItemDTO
();
BeanUtils
.
copyEntityProperties
(
sourceItem
,
createdItem
);
createdItem
.
setLineNum
(
lineNum
++);
createdItem
.
setNamespaceId
(
namespaceId
);
return
createdItem
;
}
}
apollo-portal/src/main/resources/application.yml
View file @
46931840
...
...
@@ -17,4 +17,4 @@ ctrip:
apollo
:
portal
:
env
:
local
,dev
env
:
local
apollo-portal/src/main/resources/static/img/sync-error.png
0 → 100644
View file @
46931840
4.08 KB
apollo-portal/src/main/resources/static/img/sync-succ.png
0 → 100644
View file @
46931840
3.88 KB
apollo-portal/src/main/resources/static/img/sync.png
0 → 100644
View file @
46931840
2.86 KB
apollo-portal/src/main/resources/static/index.html
View file @
46931840
...
...
@@ -76,10 +76,14 @@
<!-- bootstrap.js -->
<script
src=
"vendor/bootstrap/js/bootstrap.min.js"
type=
"text/javascript"
></script>
<!--nicescroll-->
<script
src=
"vendor/jquery.nicescroll.min.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/app.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/AppService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/EnvService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/AppUtils.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/controller/IndexController.js"
></script>
</body>
</html>
apollo-portal/src/main/resources/static/scripts/AppUtils.js
View file @
46931840
...
...
@@ -3,10 +3,32 @@ appUtil.service('AppUtil', [function () {
return
{
errorMsg
:
function
(
response
)
{
var
msg
=
"Code:"
+
response
.
status
;
if
(
response
.
data
.
message
!=
null
){
if
(
response
.
data
.
message
!=
null
)
{
msg
+=
" Msg:"
+
response
.
data
.
message
;
}
return
msg
;
},
parseParams
:
function
(
path
)
{
if
(
!
path
)
{
return
{};
}
if
(
path
.
startsWith
(
"/"
))
{
path
=
path
.
substring
(
1
,
path
.
length
);
}
var
params
=
path
.
split
(
"&"
);
var
result
=
{};
params
.
forEach
(
function
(
param
)
{
var
kv
=
param
.
split
(
"="
);
result
[
kv
[
0
]]
=
kv
[
1
];
});
return
result
;
},
cutOffString
:
function
(
str
,
maxLength
)
{
if
(
!
str
||
maxLength
<=
0
)
{
return
''
;
}
return
str
.
length
>
maxLength
?
str
.
substr
(
0
,
maxLength
)
:
str
;
}
}
}]);
apollo-portal/src/main/resources/static/scripts/PageCommon.js
0 → 100644
View file @
46931840
$
(
document
).
ready
(
function
()
{
$
(
"html"
).
niceScroll
({
styler
:
"fb"
,
cursorcolor
:
"#e8403f"
,
cursorwidth
:
'6'
,
cursorborderradius
:
'10px'
,
background
:
'#404040'
,
spacebarenabled
:
false
,
cursorborder
:
''
,
zindex
:
'1000'
});
});
apollo-portal/src/main/resources/static/scripts/app.js
View file @
46931840
...
...
@@ -11,6 +11,8 @@ var index_module = angular.module('index', ['toastr', 'app.service', 'app.util',
var
application_module
=
angular
.
module
(
'application'
,
[
'app.service'
,
'app.util'
,
'toastr'
,
'angular-loading-bar'
]);
//创建项目页面
var
create_app_module
=
angular
.
module
(
'create_app'
,
[
'ngResource'
,
'toastr'
,
'app.service'
,
'app.util'
,
'angular-loading-bar'
]);
//配置同步页面
var
sync_item_module
=
angular
.
module
(
'sync_item'
,
[
'app.service'
,
'app.util'
,
'toastr'
,
'angular-loading-bar'
]);
...
...
apollo-portal/src/main/resources/static/scripts/controller/app/AppConfigController.js
View file @
46931840
...
...
@@ -2,7 +2,8 @@ application_module.controller("AppConfigController",
[
'$scope'
,
'$location'
,
'toastr'
,
'AppService'
,
'AppUtil'
,
'ConfigService'
,
function
(
$scope
,
$location
,
toastr
,
AppService
,
AppUtil
,
ConfigService
)
{
var
appId
=
$location
.
$$url
.
split
(
"="
)[
1
];
var
appId
=
AppUtil
.
parseParams
(
$location
.
$$url
).
appid
;
var
currentUser
=
'test_user'
;
var
pageContext
=
{
appId
:
appId
,
...
...
@@ -92,16 +93,17 @@ application_module.controller("AppConfigController",
//初始化视图
if
(
$scope
.
namespaces
)
{
$scope
.
namespaces
.
forEach
(
function
(
item
)
{
item
.
isModify
=
false
;
if
(
!
viewType
){
//default text view
if
(
!
viewType
)
{
//default text view
$scope
.
switchView
(
item
,
namespace_view_type
.
TEXT
);
}
else
if
(
viewType
==
namespace_view_type
.
TABLE
)
{
}
else
if
(
viewType
==
namespace_view_type
.
TABLE
)
{
item
.
viewType
=
namespace_view_type
.
TABLE
;
}
item
.
isTextEditing
=
false
;
})
})
;
}
},
function
(
result
)
{
...
...
@@ -122,10 +124,12 @@ application_module.controller("AppConfigController",
//把表格内容解析成文本
function
parseModel2Text
(
namespace
)
{
if
(
!
namespace
.
items
)
{
return
"无配置信息"
;
}
var
result
=
""
;
var
itemCnt
=
0
;
namespace
.
items
.
forEach
(
function
(
item
)
{
if
(
item
.
item
.
key
)
{
result
+=
...
...
@@ -133,9 +137,12 @@ application_module.controller("AppConfigController",
}
else
{
result
+=
item
.
item
.
comment
+
"
\
n"
;
}
itemCnt
++
;
});
itemCnt
>
30
?
30
:
itemCnt
;
itemCnt
<
9
?
8
:
itemCnt
;
namespace
.
itemCnt
=
itemCnt
+
3
;
return
result
;
}
...
...
@@ -183,14 +190,12 @@ application_module.controller("AppConfigController",
////// table view oper //////
//查看旧值
$scope
.
queryOldValue
=
function
(
key
,
oldValue
)
{
$scope
.
queryKey
=
key
;
if
(
oldValue
==
''
)
{
$scope
.
OldValue
=
key
+
"是新添加的key"
;
}
else
{
$scope
.
OldValue
=
oldValue
;
}
$scope
.
watch
=
{};
//查看配置
$scope
.
watchItem
=
function
(
key
,
value
,
oldValue
)
{
$scope
.
watch
.
key
=
key
;
$scope
.
watch
.
value
=
value
;
$scope
.
watch
.
oldValue
=
oldValue
;
};
/////// release ///////
...
...
@@ -252,6 +257,5 @@ application_module.controller("AppConfigController",
});
};
}]);
apollo-portal/src/main/resources/static/scripts/controller/app/SyncConfigController.js
0 → 100644
View file @
46931840
sync_item_module
.
controller
(
"SyncItemController"
,
[
'$scope'
,
'$location'
,
'toastr'
,
'AppService'
,
'AppUtil'
,
'ConfigService'
,
function
(
$scope
,
$location
,
toastr
,
AppService
,
AppUtil
,
ConfigService
)
{
var
params
=
AppUtil
.
parseParams
(
$location
.
$$url
);
var
currentUser
=
'test_user'
;
$scope
.
pageContext
=
{
appId
:
params
.
appid
,
env
:
params
.
env
,
clusterName
:
params
.
clusterName
,
namespaceName
:
params
.
namespaceName
};
////// load env //////
AppService
.
load_nav_tree
(
$scope
.
pageContext
.
appId
).
then
(
function
(
result
)
{
$scope
.
clusters
=
result
.
nodes
;
$scope
.
clusters
=
[];
result
.
nodes
.
forEach
(
function
(
node
)
{
var
env
=
node
.
env
;
node
.
clusters
.
forEach
(
function
(
cluster
)
{
cluster
.
env
=
env
;
cluster
.
checked
=
false
;
$scope
.
clusters
.
push
(
cluster
);
})
});
},
function
(
result
)
{
toastr
.
error
(
AppUtil
.
errorMsg
(
result
),
"加载环境出错"
);
});
var
envAllSelected
=
false
;
$scope
.
toggleEnvsCheckedStatus
=
function
()
{
envAllSelected
=
!
envAllSelected
;
$scope
.
clusters
.
forEach
(
function
(
cluster
)
{
cluster
.
checked
=
envAllSelected
;
})
};
////// load items //////
ConfigService
.
find_items
(
$scope
.
pageContext
.
appId
,
$scope
.
pageContext
.
env
,
$scope
.
pageContext
.
clusterName
,
$scope
.
pageContext
.
namespaceName
).
then
(
function
(
result
)
{
$scope
.
sourceItems
=
result
;
$scope
.
sourceItems
.
forEach
(
function
(
item
)
{
item
.
checked
=
false
;
})
},
function
(
result
)
{
toastr
.
error
(
AppUtil
.
errorMsg
(
result
),
"加载配置出错"
);
});
var
itemAllSelected
=
false
;
$scope
.
toggleItemsCheckedStatus
=
function
()
{
itemAllSelected
=
!
itemAllSelected
;
$scope
.
sourceItems
.
forEach
(
function
(
item
)
{
item
.
checked
=
itemAllSelected
;
})
};
////// flow control ///////
$scope
.
syncItemStep
=
1
;
$scope
.
syncItemNextStep
=
function
(
offset
)
{
$scope
.
syncItemStep
+=
offset
;
};
$scope
.
syncItems
=
function
()
{
$scope
.
syncItemStep
+=
1
;
};
$scope
.
destorySync
=
function
()
{
$scope
.
syncItemStep
=
1
;
}
}]);
apollo-portal/src/main/resources/static/scripts/services/ConfigService.js
View file @
46931840
appService
.
service
(
"ConfigService"
,
[
'$resource'
,
'$q'
,
function
(
$resource
,
$q
)
{
var
config_source
=
$resource
(
""
,
{},
{
load_all_
group
s
:
{
load_all_
namespace
s
:
{
method
:
'GET'
,
isArray
:
true
,
url
:
'/apps/:appId/env/:env/clusters/:clusterName/namespaces'
},
find_items
:{
method
:
'GET'
,
isArray
:
true
,
url
:
'/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/items'
},
modify_items
:
{
method
:
'PUT'
,
url
:
'/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/items'
...
...
@@ -18,7 +23,7 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
return
{
load_all_namespaces
:
function
(
appId
,
env
,
clusterName
)
{
var
d
=
$q
.
defer
();
config_source
.
load_all_
group
s
({
config_source
.
load_all_
namespace
s
({
appId
:
appId
,
env
:
env
,
clusterName
:
clusterName
...
...
@@ -29,6 +34,20 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
});
return
d
.
promise
;
},
find_items
:
function
(
appId
,
env
,
clusterName
,
namespaceName
)
{
var
d
=
$q
.
defer
();
config_source
.
find_items
({
appId
:
appId
,
env
:
env
,
clusterName
:
clusterName
,
namespaceName
:
namespaceName
},
function
(
result
)
{
d
.
resolve
(
result
);
},
function
(
result
)
{
d
.
reject
(
result
);
});
return
d
.
promise
;
},
modify_items
:
function
(
appId
,
env
,
clusterName
,
namespaceName
,
configText
,
namespaceId
,
comment
,
modifyBy
)
{
var
d
=
$q
.
defer
();
...
...
apollo-portal/src/main/resources/static/styles/common-style.css
View file @
46931840
...
...
@@ -197,6 +197,10 @@ table th {
table-layout
:
fixed
;
}
.namespace-view-table
tr
{
cursor
:
pointer
;
}
.namespace-view-table
td
{
word-wrap
:
break-word
;
}
...
...
apollo-portal/src/main/resources/static/views/app.html
View file @
46931840
...
...
@@ -65,7 +65,16 @@
</div>
</section>
<a
class=
"list-group-item"
data-toggle=
"modal"
data-target=
"#createEnvModal"
ng-show=
"missEnvs.length > 0"
>
<a
class=
"list-group-item"
data-toggle=
"modal"
data-target=
"#syncItems"
>
<div
class=
"row"
>
<div
class=
"col-md-2"
><img
src=
"../img/sync.png"
class=
"i-20"
></div>
<div
class=
"col-md-7 hidden-xs"
>
<p
class=
"apps-description"
>
配置同步
</p>
</div>
</div>
</a>
<a
class=
"list-group-item"
data-toggle=
"modal"
data-target=
"#createEnvModal"
ng-show=
"missEnvs.length > 0"
>
<div
class=
"row"
>
<div
class=
"col-md-2"
><img
src=
"../img/plus.png"
class=
"i-20"
></div>
<div
class=
"col-md-7 hidden-xs"
>
...
...
@@ -126,9 +135,10 @@
<button
type=
"button"
class=
"btn btn-default btn-sm J_tableview_btn"
>
授权
</button>
<button
type=
"button"
class=
"btn btn-default btn-sm J_tableview_btn"
>
克隆
</button>
<a
type=
"button"
target=
"_blank"
href=
"sync.html?#/appid={{pageContext.appId}}&env={{pageContext.env}}&clusterName={{pageContext.clusterName}}&namespaceName={{namespace.namespace.namespaceName}}"
class=
"btn btn-default btn-sm J_tableview_btn"
>
同步
</a>
</div>
</div>
<div
class=
"btn-group"
role=
"group"
aria-label=
"..."
>
...
...
@@ -169,7 +179,7 @@
</header>
<!--text view-->
<textarea
class=
"form-control"
rows=
"
30
"
<textarea
class=
"form-control"
rows=
"
{{namespace.itemCnt}}
"
ng-show=
"namespace.viewType == 'text'"
ng-disabled=
"!namespace.isTextEditing"
ng-model=
"namespace.text"
>
{{namespace.text}}
...
...
@@ -177,7 +187,7 @@
<!--table view-->
<div
class=
"namespace-view-table"
>
<table
class=
"table table-bordered text-center table-hover"
<table
class=
"table table-bordered t
able-striped t
ext-center table-hover"
ng-show=
"namespace.viewType == 'table'"
>
<thead>
<tr>
...
...
@@ -200,21 +210,16 @@
</thead>
<tbody>
<tr
ng-repeat=
"config in namespace.items"
ng-class=
"{warning:config.modified}"
ng-if=
"config.item.key"
>
<tr
title=
"点击查看"
data-toggle=
"modal"
data-target=
"#oldValueModal"
ng-repeat=
"config in namespace.items"
ng-class=
"{warning:config.modified}"
ng-if=
"config.item.key"
ng-click=
"watchItem(config.item.key, config.item.value, config.oldValue)"
>
<td
width=
"25%"
>
{{config.item.key}}
{{config.item.key
| limitTo: 20}} {{config.item.key.length > 20 ? '...' : ''
}}
</td>
<td
width=
"30%"
>
<button
data-placement=
"top"
title=
"查看旧值"
class=
"glyphicon glyphicon-eye-open"
aria-hidden=
"true"
data-toggle=
"modal"
data-target=
"#oldValueModal"
ng-show=
"config.modified"
ng-click=
"queryOldValue(config.item.key, config.oldValue)"
></button>
{{config.item.value}}
{{config.item.value | limitTo: 20}} {{config.item.value.length > 20 ? '...' : ''}}
</td>
<td
width=
"20%"
>
{{config.item.comment}}
{{config.item.comment
| limitTo: 20}} {{config.item.comment.length > 20 ? '...' : ''
}}
</td>
<td
width=
"10%"
>
{{config.item.lastModifiedBy}}
...
...
@@ -282,19 +287,22 @@
</div>
<!-- view old value Modal -->
<div
class=
"modal fade
"
id=
"oldValueModal"
tabindex=
"-1"
role=
"dialog"
>
<div
class=
"modal-dialog
modal-sm
"
role=
"document"
>
<div
class=
"modal fade"
id=
"oldValueModal"
tabindex=
"-1"
role=
"dialog"
>
<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"
>
旧值
</h4>
<h4
class=
"modal-title"
>
{{watch.key}}
</h4>
</div>
<div
class=
"modal-body"
style=
"word-wrap: break-word;"
>
{{watch.value}}
<div
ng-show=
"watch.oldValue"
>
<hr>
老的值:{{watch.oldValue}}
</div>
<div
class=
"modal-body"
>
{{OldValue}}
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
class=
"btn btn-default"
data-dismiss=
"modal"
>
关闭
</button>
<button
type=
"button"
class=
"btn btn-default"
data-dismiss=
"modal"
>
Close
</button>
</div>
</div>
...
...
@@ -375,6 +383,8 @@
</div>
</div>
</div>
</div>
</div>
</div>
...
...
@@ -414,24 +424,7 @@
<!--controller-->
<script
type=
"application/javascript"
src=
"../scripts/controller/app/AppConfigController.js"
></script>
<script
type=
"application/javascript"
>
$
(
document
).
ready
(
function
()
{
$
(
"html"
).
niceScroll
({
styler
:
"fb"
,
cursorcolor
:
"#e8403f"
,
cursorwidth
:
'6'
,
cursorborderradius
:
'10px'
,
background
:
'#404040'
,
spacebarenabled
:
false
,
cursorborder
:
''
,
zindex
:
'1000'
});
});
$
(
function
()
{
$
(
'[data-toggle="tooltip"]'
).
tooltip
()
});
</script>
<script
type=
"application/javascript"
src=
"../scripts/PageCommon.js"
></script>
</body>
</html>
apollo-portal/src/main/resources/static/views/sync.html
0 → 100644
View file @
46931840
<!doctype html>
<html
ng-app=
"sync_item"
>
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<!-- styles -->
<link
rel=
"stylesheet"
type=
"text/css"
href=
"../vendor/bootstrap/css/bootstrap.min.css"
>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"../vendor/angular/angular-toastr-1.4.1.min.css"
>
<link
rel=
"stylesheet"
type=
"text/css"
media=
'all'
href=
"../vendor/angular/loading-bar.min.css"
>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"../styles/common-style.css"
>
<title>
同步配置
</title>
</head>
<body
ng-controller=
"SyncItemController"
>
<div
ng-include=
"'common/nav.html'"
></div>
<div
class=
"container-fluid apollo-container"
>
<section
class=
"panel col-md-offset-1 col-md-10"
>
<header
class=
"panel-heading"
>
<div
class=
"row"
>
<div
class=
"col-md-3"
>
<h4
class=
"modal-title"
>
同步配置
<small
ng-show=
"syncItemStep == 1"
>
(第一步:选择同步信息)
</small>
<small
ng-show=
"syncItemStep == 2"
>
(第二步:检查Diff)
</small>
</h4>
</div>
<div
class=
"col-md-9 text-right"
>
<button
type=
"button"
class=
"btn btn-primary"
ng-show=
"syncItemStep > 1 && syncItemStep < 3"
ng-click=
"syncItemNextStep(-1)"
>
上一步
</button>
<button
type=
"button"
class=
"btn btn-primary"
ng-show=
"syncItemStep < 2"
ng-click=
"syncItemNextStep(1)"
>
下一步
</button>
<button
type=
"button"
class=
"btn btn-success"
ng-show=
"syncItemStep == 2"
ng-click=
"syncItems()"
>
同步
</button>
<button
type=
"button"
class=
"btn btn-primary"
data-dismiss=
"modal"
ng-show=
"syncItemStep == 3"
ng-click=
"destorySync()"
>
返回
</button>
</div>
</div>
</header>
<div
class=
"panel-body"
>
<div
class=
"row"
ng-show=
"syncItemStep == 1"
>
<div
class=
"form-horizontal"
>
<div
class=
"form-group"
>
<label
class=
"col-sm-2 control-label"
>
同步到那个集群
</label>
<div
class=
"col-sm-6"
>
<table
class=
"table table-hover"
>
<thead>
<tr>
<td><input
type=
"checkbox"
ng-click=
"toggleEnvsCheckedStatus()"
></td>
</td>
<td>
环境
</td>
<td>
集群
</td>
</tr>
</thead>
<tbody>
<tr
ng-repeat=
"cluster in clusters"
>
<td
width=
"10%"
><input
type=
"checkbox"
ng-checked=
"cluster.checked"
></td>
<td
width=
"30%"
>
{{cluster.env}}
</td>
<td
width=
"60%"
>
{{cluster.name}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<hr>
</div>
<div
class=
"row"
ng-show=
"syncItemStep == 1"
style=
"margin-top: 10px;"
>
<div
class=
"form-horizontal"
>
<div
class=
"col-sm-2 text-right"
>
<label
class=
"control-label"
>
需要同步的配置
</label>
</div>
<div
class=
"col-sm-10"
>
<table
class=
"table table-bordered table-striped table-hover"
>
<thead>
<tr>
<td><input
type=
"checkbox"
ng-click=
"toggleItemsCheckedStatus()"
></td>
<td>
key
</td>
<td>
value
</td>
<td>
comment
</td>
</tr>
</thead>
<tbody>
<tr
ng-repeat=
"item in sourceItems"
>
<td
width=
"10%"
><input
type=
"checkbox"
ng-checked=
"item.checked"
></td>
<td
width=
"20%"
>
{{item.key}}
</td>
<td
width=
"50%"
>
{{item.value | limitTo: 36}} {{item.value.length > 36 ? '...' : ''}}
</td>
<td
width=
"20%"
>
{{item.comment | limitTo: 15}}{{item.comment.length > 15 ? '...' : ''}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!--step 2-->
<div
class=
"row"
ng-show=
"syncItemStep == 2"
>
<h4
class=
"text-center"
>
环境:fat 集群:default
</h4>
<hr>
<div
class=
"row"
style=
"margin-top: 10px;"
>
<div
class=
"form-horizontal"
>
<label
class=
"col-sm-2 control-label"
>
新增的配置
</label>
<div
class=
"col-sm-9"
>
<table
class=
"table table-bordered table-hover"
>
<thead>
<tr>
<td>
key
</td>
<td>
value
</td>
</tr>
</thead>
<tbody>
<tr>
<td
width=
"30%"
>
k1
</td>
<td
width=
"60%"
>
v1
</td>
</tr>
<tr>
<td
width=
"30%"
>
k1
</td>
<td
width=
"60%"
>
v1
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div
class=
"row"
ng-show=
"syncItemStep == 2"
>
<div
class=
"row"
style=
"margin-top: 10px;"
>
<div
class=
"form-horizontal"
>
<label
class=
"col-sm-2 control-label"
>
更新的配置
</label>
<div
class=
"col-sm-9"
>
<table
class=
"table table-bordered table-striped table-hover"
>
<thead>
<tr>
<td>
key
</td>
<td>
value
</td>
</tr>
</thead>
<tbody>
<tr>
<td
width=
"30%"
>
k1
</td>
<td
width=
"60%"
>
v1
</td>
</tr>
<tr>
<td
width=
"30%"
>
k1
</td>
<td
width=
"60%"
>
v1
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!--step 3-->
<div
class=
"row text-center"
ng-show=
"syncItemStep == 3"
>
<img
src=
"../img/sync-succ.png"
style=
"height: 100px; width: 100px"
>
<h3>
同步成功!
</h3>
</div>
</div>
</section>
</div>
<div
ng-include=
"'common/footer.html'"
></div>
<!--angular-->
<script
src=
"../vendor/angular/angular.min.js"
></script>
<script
src=
"../vendor/angular/angular-route.min.js"
></script>
<script
src=
"../vendor/angular/angular-resource.min.js"
></script>
<script
src=
"../vendor/angular/angular-toastr-1.4.1.tpls.min.js"
></script>
<script
src=
"../vendor/angular/loading-bar.min.js"
></script>
<!-- jquery.js -->
<script
src=
"../vendor/jquery.js"
type=
"text/javascript"
></script>
<!-- bootstrap.js -->
<script
src=
"../vendor/bootstrap/js/bootstrap.min.js"
type=
"text/javascript"
></script>
<!--nicescroll-->
<script
src=
"../vendor/jquery.nicescroll.min.js"
></script>
<!--biz-->
<script
type=
"application/javascript"
src=
"../scripts/app.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/AppService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/ConfigService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/AppUtils.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/controller/app/SyncConfigController.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/PageCommon.js"
></script>
</body>
</html>
apollo-portal/src/test/java/com/ctrip/apollo/portal/ConfigServiceTest.java
View file @
46931840
package
com
.
ctrip
.
apollo
.
portal
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.core.dto.ItemChangeSets
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.core.dto.NamespaceDTO
;
import
com.ctrip.apollo.core.dto.ReleaseDTO
;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.apollo.portal.api.AdminServiceAPI
;
import
com.ctrip.apollo.portal.entity.ItemDiffs
;
import
com.ctrip.apollo.portal.entity.NamespaceIdentifer
;
import
com.ctrip.apollo.portal.entity.NamespaceVO
;
import
com.ctrip.apollo.portal.entity.form.NamespaceTextModel
;
import
com.ctrip.apollo.portal.service.ConfigService
;
...
...
@@ -127,4 +130,110 @@ public class ConfigServiceTest {
return
Arrays
.
asList
(
item1
,
item2
,
item3
);
}
@Test
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_DEFAULT
;
List
<
NamespaceIdentifer
>
namespaceIdentifers
=
generateNamespaceIdentifer
(
appId
,
env
,
clusterName
,
namespaceName
);
NamespaceDTO
namespaceDTO
=
generateNamespaceDTO
(
appId
,
clusterName
,
namespaceName
);
when
(
namespaceAPI
.
loadNamespace
(
appId
,
Env
.
valueOf
(
env
),
clusterName
,
namespaceName
)).
thenReturn
(
namespaceDTO
);
when
(
itemAPI
.
findItems
(
appId
,
Env
.
valueOf
(
env
),
clusterName
,
namespaceName
)).
thenReturn
(
null
);
List
<
ItemDiffs
>
itemDiffses
=
configService
.
compare
(
sourceItems
,
namespaceIdentifers
);
assertEquals
(
1
,
itemDiffses
.
size
());
ItemDiffs
itemDiffs
=
itemDiffses
.
get
(
0
);
ItemChangeSets
changeSets
=
itemDiffs
.
getDiffs
();
assertEquals
(
0
,
changeSets
.
getUpdateItems
().
size
());
assertEquals
(
0
,
changeSets
.
getDeleteItems
().
size
());
List
<
ItemDTO
>
createItems
=
changeSets
.
getCreateItems
();
ItemDTO
createItem
=
createItems
.
get
(
0
);
assertEquals
(
1
,
createItem
.
getLineNum
());
assertEquals
(
"a"
,
createItem
.
getKey
());
assertEquals
(
"b"
,
createItem
.
getValue
());
assertEquals
(
"comment"
,
createItem
.
getComment
());
}
@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
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
);
List
<
ItemDTO
>
targetItems
=
Arrays
.
asList
(
targetItem1
,
targetItem2
,
targetItem3
);
String
appId
=
"6666"
,
env
=
"LOCAL"
,
clusterName
=
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
namespaceName
=
ConfigConsts
.
NAMESPACE_DEFAULT
;
List
<
NamespaceIdentifer
>
namespaceIdentifers
=
generateNamespaceIdentifer
(
appId
,
env
,
clusterName
,
namespaceName
);
NamespaceDTO
namespaceDTO
=
generateNamespaceDTO
(
appId
,
clusterName
,
namespaceName
);
when
(
namespaceAPI
.
loadNamespace
(
appId
,
Env
.
valueOf
(
env
),
clusterName
,
namespaceName
)).
thenReturn
(
namespaceDTO
);
when
(
itemAPI
.
findItems
(
appId
,
Env
.
valueOf
(
env
),
clusterName
,
namespaceName
)).
thenReturn
(
targetItems
);
List
<
ItemDiffs
>
itemDiffses
=
configService
.
compare
(
sourceItems
,
namespaceIdentifers
);
assertEquals
(
1
,
itemDiffses
.
size
());
ItemDiffs
itemDiffs
=
itemDiffses
.
get
(
0
);
ItemChangeSets
changeSets
=
itemDiffs
.
getDiffs
();
assertEquals
(
0
,
changeSets
.
getDeleteItems
().
size
());
assertEquals
(
2
,
changeSets
.
getUpdateItems
().
size
());
assertEquals
(
1
,
changeSets
.
getCreateItems
().
size
());
NamespaceIdentifer
namespaceIdentifer
=
itemDiffs
.
getNamespace
();
assertEquals
(
appId
,
namespaceIdentifer
.
getAppId
());
assertEquals
(
Env
.
valueOf
(
"LOCAL"
),
namespaceIdentifer
.
getEnv
());
assertEquals
(
clusterName
,
namespaceIdentifer
.
getClusterName
());
assertEquals
(
namespaceName
,
namespaceIdentifer
.
getNamespaceName
());
ItemDTO
createdItem
=
changeSets
.
getCreateItems
().
get
(
0
);
assertEquals
(
"newKey"
,
createdItem
.
getKey
());
assertEquals
(
"c"
,
createdItem
.
getValue
());
assertEquals
(
"comment"
,
createdItem
.
getComment
());
assertEquals
(
4
,
createdItem
.
getLineNum
());
List
<
ItemDTO
>
updateItems
=
changeSets
.
getUpdateItems
();
ItemDTO
updateItem1
=
updateItems
.
get
(
0
);
ItemDTO
updateItem2
=
updateItems
.
get
(
1
);
assertEquals
(
"c"
,
updateItem1
.
getKey
());
assertEquals
(
"newValue"
,
updateItem1
.
getValue
());
assertEquals
(
"comment"
,
updateItem1
.
getComment
());
assertEquals
(
2
,
updateItem1
.
getLineNum
());
assertEquals
(
"d"
,
updateItem2
.
getKey
());
assertEquals
(
"b"
,
updateItem2
.
getValue
());
assertEquals
(
"newComment"
,
updateItem2
.
getComment
());
assertEquals
(
3
,
updateItem2
.
getLineNum
());
}
private
NamespaceDTO
generateNamespaceDTO
(
String
appId
,
String
clusterName
,
String
namespaceName
){
NamespaceDTO
namespaceDTO
=
new
NamespaceDTO
();
namespaceDTO
.
setAppId
(
appId
);
namespaceDTO
.
setId
(
1
);
namespaceDTO
.
setClusterName
(
clusterName
);
namespaceDTO
.
setNamespaceName
(
namespaceName
);
return
namespaceDTO
;
}
private
List
<
NamespaceIdentifer
>
generateNamespaceIdentifer
(
String
appId
,
String
env
,
String
clusterName
,
String
namespaceName
){
NamespaceIdentifer
targetNamespace
=
new
NamespaceIdentifer
();
targetNamespace
.
setAppId
(
appId
);
targetNamespace
.
setEnv
(
env
);
targetNamespace
.
setClusterName
(
clusterName
);
targetNamespace
.
setNamespaceName
(
namespaceName
);
return
Arrays
.
asList
(
targetNamespace
);
}
}
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