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
4c2d7f44
Commit
4c2d7f44
authored
Apr 12, 2016
by
Jason Song
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #77 from lepdou/v2
portal文本初步编辑
parents
a3ba41c0
2dc30c78
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
696 additions
and
64 deletions
+696
-64
ItemController.java
.../ctrip/apollo/adminservice/controller/ItemController.java
+6
-2
ItemChangeSets.java
...c/main/java/com/ctrip/apollo/core/dto/ItemChangeSets.java
+70
-0
ItemDTO.java
...core/src/main/java/com/ctrip/apollo/core/dto/ItemDTO.java
+13
-0
SimpleRestfulResponse.java
...a/com/ctrip/apollo/core/entity/SimpleRestfulResponse.java
+31
-0
AdminServiceAPI.java
...ain/java/com/ctrip/apollo/portal/api/AdminServiceAPI.java
+49
-35
ConfigController.java
.../com/ctrip/apollo/portal/controller/ConfigController.java
+27
-2
SimpleResponse.java
...n/java/com/ctrip/apollo/portal/entity/SimpleResponse.java
+28
-0
ClusterService.java
.../java/com/ctrip/apollo/portal/service/ClusterService.java
+1
-1
ConfigService.java
...n/java/com/ctrip/apollo/portal/service/ConfigService.java
+18
-5
ConfigTextResolver.java
...apollo/portal/service/txtresolver/ConfigTextResolver.java
+14
-0
SimpleKVCResolver.java
.../apollo/portal/service/txtresolver/SimpleKVCResolver.java
+89
-0
TextResolverResult.java
...apollo/portal/service/txtresolver/TextResolverResult.java
+67
-0
BeanUtils.java
...src/main/java/com/ctrip/apollo/portal/util/BeanUtils.java
+213
-0
AppConfigController.js
...rces/static/scripts/controller/app/AppConfigController.js
+35
-12
ConfigService.js
...c/main/resources/static/scripts/services/ConfigService.js
+29
-5
index.html
apollo-portal/src/main/resources/static/views/app/index.html
+6
-2
No files found.
apollo-adminservice/src/main/java/com/ctrip/apollo/adminservice/controller/ItemController.java
View file @
4c2d7f44
...
@@ -4,13 +4,16 @@ import java.util.List;
...
@@ -4,13 +4,16 @@ import java.util.List;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.PathVariable
;
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.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
import
com.ctrip.apollo.biz.entity.Item
;
import
com.ctrip.apollo.biz.entity.Item
;
import
com.ctrip.apollo.biz.service.ItemService
;
import
com.ctrip.apollo.biz.service.ItemService
;
import
com.ctrip.apollo.biz.service.ViewService
;
import
com.ctrip.apollo.biz.service.ViewService
;
import
com.ctrip.apollo.biz.utils.BeanUtils
;
import
com.ctrip.apollo.biz.utils.BeanUtils
;
import
com.ctrip.apollo.core.dto.ItemChangeSets
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
@RestController
@RestController
...
@@ -24,8 +27,8 @@ public class ItemController {
...
@@ -24,8 +27,8 @@ public class ItemController {
@RequestMapping
(
"/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items"
)
@RequestMapping
(
"/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items"
)
public
List
<
ItemDTO
>
findItems
(
@PathVariable
(
"appId"
)
String
appId
,
public
List
<
ItemDTO
>
findItems
(
@PathVariable
(
"appId"
)
String
appId
,
@PathVariable
(
"clusterName"
)
String
clusterName
,
@PathVariable
(
"clusterName"
)
String
clusterName
,
@PathVariable
(
"namespaceName"
)
String
namespaceName
)
{
@PathVariable
(
"namespaceName"
)
String
namespaceName
)
{
List
<
Item
>
items
=
viewService
.
findItems
(
appId
,
clusterName
,
namespaceName
);
List
<
Item
>
items
=
viewService
.
findItems
(
appId
,
clusterName
,
namespaceName
);
return
BeanUtils
.
batchTransform
(
ItemDTO
.
class
,
items
);
return
BeanUtils
.
batchTransform
(
ItemDTO
.
class
,
items
);
}
}
...
@@ -35,4 +38,5 @@ public class ItemController {
...
@@ -35,4 +38,5 @@ public class ItemController {
Item
item
=
itemService
.
findOne
(
itemId
);
Item
item
=
itemService
.
findOne
(
itemId
);
return
BeanUtils
.
transfrom
(
ItemDTO
.
class
,
item
);
return
BeanUtils
.
transfrom
(
ItemDTO
.
class
,
item
);
}
}
}
}
apollo-core/src/main/java/com/ctrip/apollo/core/dto/ItemChangeSets.java
0 → 100644
View file @
4c2d7f44
package
com
.
ctrip
.
apollo
.
core
.
dto
;
import
java.util.LinkedList
;
import
java.util.List
;
/**
* storage cud result
*/
public
class
ItemChangeSets
{
private
String
modifyBy
;
private
List
<
ItemDTO
>
createItems
;
private
List
<
ItemDTO
>
updateItems
;
private
List
<
ItemDTO
>
deletedItems
;
public
void
addCreatedItem
(
ItemDTO
item
)
{
if
(
createItems
==
null
)
{
createItems
=
new
LinkedList
<>();
}
createItems
.
add
(
item
);
}
public
void
addupdateItem
(
ItemDTO
item
)
{
if
(
updateItems
==
null
)
{
updateItems
=
new
LinkedList
<>();
}
updateItems
.
add
(
item
);
}
public
void
addDeletedItem
(
ItemDTO
item
)
{
if
(
deletedItems
==
null
)
{
deletedItems
=
new
LinkedList
<>();
}
deletedItems
.
add
(
item
);
}
public
List
<
ItemDTO
>
getCreateItems
()
{
return
createItems
;
}
public
List
<
ItemDTO
>
getUpdateItems
()
{
return
updateItems
;
}
public
List
<
ItemDTO
>
getDeletedItems
()
{
return
deletedItems
;
}
public
void
setCreateItems
(
List
<
ItemDTO
>
createItems
)
{
this
.
createItems
=
createItems
;
}
public
void
setUpdateItems
(
List
<
ItemDTO
>
updateItems
)
{
this
.
updateItems
=
updateItems
;
}
public
void
setDeletedItems
(
List
<
ItemDTO
>
deletedItems
)
{
this
.
deletedItems
=
deletedItems
;
}
public
String
getModifyBy
()
{
return
modifyBy
;
}
public
void
setModifyBy
(
String
modifyBy
)
{
this
.
modifyBy
=
modifyBy
;
}
}
apollo-core/src/main/java/com/ctrip/apollo/core/dto/ItemDTO.java
View file @
4c2d7f44
...
@@ -82,4 +82,17 @@ public class ItemDTO {
...
@@ -82,4 +82,17 @@ public class ItemDTO {
public
void
setDataChangeLastModifiedTime
(
Date
dataChangeLastModifiedTime
)
{
public
void
setDataChangeLastModifiedTime
(
Date
dataChangeLastModifiedTime
)
{
this
.
dataChangeLastModifiedTime
=
dataChangeLastModifiedTime
;
this
.
dataChangeLastModifiedTime
=
dataChangeLastModifiedTime
;
}
}
@Override
public
String
toString
()
{
return
"ItemDTO{"
+
"id="
+
id
+
", namespaceId="
+
namespaceId
+
", key='"
+
key
+
'\''
+
", value='"
+
value
+
'\''
+
", comment='"
+
comment
+
'\''
+
", dataChangeLastModifiedBy='"
+
dataChangeLastModifiedBy
+
'\''
+
", dataChangeLastModifiedTime="
+
dataChangeLastModifiedTime
+
'}'
;
}
}
}
apollo-core/src/main/java/com/ctrip/apollo/core/entity/SimpleRestfulResponse.java
0 → 100644
View file @
4c2d7f44
package
com
.
ctrip
.
apollo
.
core
.
entity
;
/**
* declare biz code and simple msg. maybe http response code is 200.
*/
public
class
SimpleRestfulResponse
{
private
int
code
;
private
String
msg
;
public
SimpleRestfulResponse
(
int
code
,
String
msg
){
this
.
code
=
code
;
this
.
msg
=
msg
;
}
public
int
getCode
()
{
return
code
;
}
public
void
setCode
(
int
code
)
{
this
.
code
=
code
;
}
public
String
getMsg
()
{
return
msg
;
}
public
void
setMsg
(
String
msg
)
{
this
.
msg
=
msg
;
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/api/AdminServiceAPI.java
View file @
4c2d7f44
...
@@ -11,16 +11,20 @@ import com.ctrip.apollo.core.utils.StringUtils;
...
@@ -11,16 +11,20 @@ import com.ctrip.apollo.core.utils.StringUtils;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
java.util.Arrays
;
import
java.util.List
;
@Service
@Service
public
class
AdminServiceAPI
{
public
class
AdminServiceAPI
{
@Service
@Service
public
static
class
AppAPI
extends
API
{
public
static
class
AppAPI
extends
API
{
public
static
String
APP_API
=
"/apps"
;
public
static
String
APP_API
=
"/apps"
;
public
AppDTO
[]
getApps
(
Apollo
.
Env
env
)
{
public
List
<
AppDTO
>
getApps
(
Apollo
.
Env
env
)
{
return
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
APP_API
,
AppDTO
[].
class
);
return
Arrays
.
asList
(
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
APP_API
,
AppDTO
[].
class
)
);
}
}
}
}
...
@@ -28,58 +32,68 @@ public class AdminServiceAPI {
...
@@ -28,58 +32,68 @@ public class AdminServiceAPI {
@Service
@Service
public
static
class
NamespaceAPI
extends
API
{
public
static
class
NamespaceAPI
extends
API
{
public
NamespaceDTO
[]
findGroupsByAppAndCluster
(
String
appId
,
Apollo
.
Env
env
,
public
List
<
NamespaceDTO
>
findGroupsByAppAndCluster
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
)
{
String
clusterName
)
{
if
(
StringUtils
.
isContainEmpty
(
appId
,
clusterName
))
{
if
(
StringUtils
.
isContainEmpty
(
appId
,
clusterName
))
{
return
null
;
return
null
;
}
}
return
restTemplate
.
getForObject
(
return
Arrays
.
asList
(
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
String
.
format
(
"apps/%s/clusters/%s/namespaces"
,
appId
,
clusterName
),
getAdminServiceHost
(
env
)
+
String
.
format
(
"apps/%s/clusters/%s/namespaces"
,
appId
,
clusterName
),
NamespaceDTO
[].
class
);
NamespaceDTO
[].
class
)
)
;
}
}
}
@Service
public
static
class
ItemAPI
extends
API
{
public
ItemDTO
[]
findItems
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
,
String
namespace
)
{
public
NamespaceDTO
loadNamespace
(
String
appId
,
Apollo
.
Env
env
,
if
(
StringUtils
.
isContainEmpty
(
appId
,
clusterName
,
namespace
))
{
String
clusterName
,
String
namespaceName
)
{
if
(
StringUtils
.
isContainEmpty
(
appId
,
clusterName
,
namespaceName
))
{
return
null
;
return
null
;
}
}
return
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
return
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
String
String
.
format
(
"apps/%s/clusters/%s/namespaces/%s"
,
appId
,
clusterName
,
.
format
(
"apps/%s/clusters/%s/namespaces/%s/items"
,
appId
,
namespaceName
),
NamespaceDTO
.
class
);
clusterName
,
namespace
),
}
ItemDTO
[].
class
);
}
}
}
@Service
public
static
class
ItemAPI
extends
API
{
@Service
public
List
<
ItemDTO
>
findItems
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
,
String
namespace
)
{
public
static
class
ClusterAPI
extends
API
{
if
(
StringUtils
.
isContainEmpty
(
appId
,
clusterName
,
namespace
))
{
return
null
;
}
public
ClusterDTO
[]
findClustersByApp
(
String
appId
,
Apollo
.
Env
env
)
{
return
Arrays
.
asList
(
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
String
if
(
StringUtils
.
isContainEmpty
(
appId
))
{
.
format
(
"apps/%s/clusters/%s/namespaces/%s/items"
,
appId
,
return
null
;
clusterName
,
namespace
),
ItemDTO
[].
class
));
}
}
return
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
String
.
format
(
"apps/%s/clusters"
,
appId
),
ClusterDTO
[].
class
);
}
}
}
@Service
@Service
public
static
class
ReleaseAPI
extends
API
{
public
static
class
ClusterAPI
extends
API
{
public
ReleaseDTO
loadLatestRelease
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
,
String
namespace
){
public
List
<
ClusterDTO
>
findClustersByApp
(
String
appId
,
Apollo
.
Env
env
)
{
if
(
StringUtils
.
isContainEmpty
(
appId
,
clusterName
,
namespace
)){
if
(
StringUtils
.
isContainEmpty
(
appId
))
{
return
null
;
return
null
;
}
return
Arrays
.
asList
(
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
String
.
format
(
"apps/%s/clusters"
,
appId
),
ClusterDTO
[].
class
));
}
}
return
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
String
.
format
(
"apps/%s/clusters/%s/namespaces/%s/releases/latest"
,
appId
,
clusterName
,
namespace
),
ReleaseDTO
.
class
);
}
}
}
}
@Service
public
static
class
ReleaseAPI
extends
API
{
public
ReleaseDTO
loadLatestRelease
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
,
String
namespace
)
{
if
(
StringUtils
.
isContainEmpty
(
appId
,
clusterName
,
namespace
))
{
return
null
;
}
return
restTemplate
.
getForObject
(
getAdminServiceHost
(
env
)
+
String
.
format
(
"apps/%s/clusters/%s/namespaces/%s/releases/latest"
,
appId
,
clusterName
,
namespace
),
ReleaseDTO
.
class
);
}
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/controller/ConfigController.java
View file @
4c2d7f44
...
@@ -2,13 +2,19 @@ package com.ctrip.apollo.portal.controller;
...
@@ -2,13 +2,19 @@ package com.ctrip.apollo.portal.controller;
import
com.ctrip.apollo.Apollo
;
import
com.ctrip.apollo.Apollo
;
import
com.ctrip.apollo.core.entity.SimpleRestfulResponse
;
import
com.ctrip.apollo.core.utils.StringUtils
;
import
com.ctrip.apollo.core.utils.StringUtils
;
import
com.ctrip.apollo.portal.entity.NamespaceVO
;
import
com.ctrip.apollo.portal.entity.NamespaceVO
;
import
com.ctrip.apollo.portal.entity.SimpleResponse
;
import
com.ctrip.apollo.portal.service.ConfigService
;
import
com.ctrip.apollo.portal.service.ConfigService
;
import
com.ctrip.apollo.portal.service.txtresolver.TextResolverResult
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
import
java.util.List
;
...
@@ -21,11 +27,30 @@ public class ConfigController {
...
@@ -21,11 +27,30 @@ public class ConfigController {
private
ConfigService
configService
;
private
ConfigService
configService
;
@RequestMapping
(
"/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces"
)
@RequestMapping
(
"/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces"
)
public
List
<
NamespaceVO
>
findNamespaces
(
@PathVariable
String
appId
,
@PathVariable
String
env
,
@PathVariable
String
clusterName
){
public
List
<
NamespaceVO
>
findNamespaces
(
@PathVariable
String
appId
,
@PathVariable
String
env
,
if
(
StringUtils
.
isContainEmpty
(
appId
,
env
,
clusterName
)){
@PathVariable
String
clusterName
)
{
if
(
StringUtils
.
isContainEmpty
(
appId
,
env
,
clusterName
))
{
throw
new
IllegalArgumentException
(
"app id and cluster name can not be empty"
);
throw
new
IllegalArgumentException
(
"app id and cluster name can not be empty"
);
}
}
return
configService
.
findNampspaces
(
appId
,
Apollo
.
Env
.
valueOf
(
env
),
clusterName
);
return
configService
.
findNampspaces
(
appId
,
Apollo
.
Env
.
valueOf
(
env
),
clusterName
);
}
}
@RequestMapping
(
value
=
"/apps/{appId}/env/{env}/clusters/{clusterName}/namespaces/{namespaceName}/modify"
,
method
=
RequestMethod
.
GET
)
public
ResponseEntity
<
SimpleRestfulResponse
>
modifyConfigs
(
@PathVariable
String
appId
,
@PathVariable
String
env
,
@PathVariable
String
clusterName
,
@PathVariable
String
namespaceName
,
String
configText
)
{
TextResolverResult
result
=
configService
.
resolve
(
appId
,
Apollo
.
Env
.
valueOf
(
env
),
clusterName
,
namespaceName
,
configText
);
TextResolverResult
.
Code
code
=
result
.
getCode
();
if
(
code
==
TextResolverResult
.
Code
.
OK
)
{
return
ResponseEntity
.
status
(
HttpStatus
.
OK
).
body
(
new
SimpleRestfulResponse
(
code
.
getValue
(),
"success"
));
}
else
{
return
ResponseEntity
.
status
(
HttpStatus
.
OK
)
.
body
(
new
SimpleRestfulResponse
(
code
.
getValue
(),
code
.
getBaseMsg
()
+
result
.
getExtensionMsg
()));
}
}
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/entity/SimpleResponse.java
0 → 100644
View file @
4c2d7f44
package
com
.
ctrip
.
apollo
.
portal
.
entity
;
public
class
SimpleResponse
{
private
int
code
;
private
String
msg
;
public
SimpleResponse
(
int
code
,
String
msg
){
this
.
code
=
code
;
this
.
msg
=
msg
;
}
public
int
getCode
()
{
return
code
;
}
public
void
setCode
(
int
code
)
{
this
.
code
=
code
;
}
public
String
getMsg
()
{
return
msg
;
}
public
void
setMsg
(
String
msg
)
{
this
.
msg
=
msg
;
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/service/ClusterService.java
View file @
4c2d7f44
...
@@ -17,7 +17,7 @@ public class ClusterService {
...
@@ -17,7 +17,7 @@ public class ClusterService {
private
AdminServiceAPI
.
ClusterAPI
clusterAPI
;
private
AdminServiceAPI
.
ClusterAPI
clusterAPI
;
public
List
<
ClusterDTO
>
findClusters
(
Apollo
.
Env
env
,
String
appId
){
public
List
<
ClusterDTO
>
findClusters
(
Apollo
.
Env
env
,
String
appId
){
return
Arrays
.
asList
(
clusterAPI
.
findClustersByApp
(
appId
,
env
)
);
return
clusterAPI
.
findClustersByApp
(
appId
,
env
);
}
}
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/service/ConfigService.java
View file @
4c2d7f44
...
@@ -7,15 +7,17 @@ import org.springframework.beans.factory.annotation.Autowired;
...
@@ -7,15 +7,17 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
com.ctrip.apollo.Apollo
;
import
com.ctrip.apollo.Apollo
;
import
com.ctrip.apollo.core.dto.ItemChangeSets
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.core.dto.NamespaceDTO
;
import
com.ctrip.apollo.core.dto.NamespaceDTO
;
import
com.ctrip.apollo.core.dto.ReleaseDTO
;
import
com.ctrip.apollo.core.dto.ReleaseDTO
;
import
com.ctrip.apollo.portal.api.AdminServiceAPI
;
import
com.ctrip.apollo.portal.api.AdminServiceAPI
;
import
com.ctrip.apollo.portal.entity.NamespaceVO
;
import
com.ctrip.apollo.portal.entity.NamespaceVO
;
import
com.ctrip.apollo.portal.service.txtresolver.ConfigTextResolver
;
import
com.ctrip.apollo.portal.service.txtresolver.TextResolverResult
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.LinkedList
;
...
@@ -34,13 +36,14 @@ public class ConfigService {
...
@@ -34,13 +36,14 @@ public class ConfigService {
@Autowired
@Autowired
private
AdminServiceAPI
.
ReleaseAPI
releaseAPI
;
private
AdminServiceAPI
.
ReleaseAPI
releaseAPI
;
private
ObjectMapper
objectMapper
=
new
ObjectMapper
();
@Autowired
private
ConfigTextResolver
resolver
;
private
ObjectMapper
objectMapper
=
new
ObjectMapper
();
public
List
<
NamespaceVO
>
findNampspaces
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
)
{
public
List
<
NamespaceVO
>
findNampspaces
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
)
{
List
<
NamespaceDTO
>
namespaces
=
Arrays
.
asList
(
List
<
NamespaceDTO
>
namespaces
=
groupAPI
.
findGroupsByAppAndCluster
(
appId
,
env
,
clusterName
);
groupAPI
.
findGroupsByAppAndCluster
(
appId
,
env
,
clusterName
));
if
(
namespaces
==
null
||
namespaces
.
size
()
==
0
)
{
if
(
namespaces
==
null
||
namespaces
.
size
()
==
0
)
{
return
Collections
.
EMPTY_LIST
;
return
Collections
.
EMPTY_LIST
;
}
}
...
@@ -53,6 +56,16 @@ public class ConfigService {
...
@@ -53,6 +56,16 @@ public class ConfigService {
return
namespaceVOs
;
return
namespaceVOs
;
}
}
public
TextResolverResult
resolve
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
,
String
namespaceName
,
String
configText
)
{
TextResolverResult
result
=
resolver
.
resolve
(
configText
,
itemAPI
.
findItems
(
appId
,
env
,
clusterName
,
namespaceName
));
if
(
result
.
getCode
()
==
TextResolverResult
.
Code
.
OK
)
{
ItemChangeSets
changeSets
=
result
.
getChangeSets
();
//invoke admin service
}
return
result
;
}
private
NamespaceVO
parseNamespace
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
,
NamespaceDTO
namespace
)
{
private
NamespaceVO
parseNamespace
(
String
appId
,
Apollo
.
Env
env
,
String
clusterName
,
NamespaceDTO
namespace
)
{
NamespaceVO
namespaceVO
=
new
NamespaceVO
();
NamespaceVO
namespaceVO
=
new
NamespaceVO
();
...
@@ -75,7 +88,7 @@ public class ConfigService {
...
@@ -75,7 +88,7 @@ public class ConfigService {
}
}
//not release config items
//not release config items
List
<
ItemDTO
>
items
=
Arrays
.
asList
(
itemAPI
.
findItems
(
appId
,
env
,
clusterName
,
namespaceName
)
);
List
<
ItemDTO
>
items
=
itemAPI
.
findItems
(
appId
,
env
,
clusterName
,
namespaceName
);
int
modifiedItemCnt
=
0
;
int
modifiedItemCnt
=
0
;
for
(
ItemDTO
itemDTO
:
items
)
{
for
(
ItemDTO
itemDTO
:
items
)
{
...
...
apollo-portal/src/main/java/com/ctrip/apollo/portal/service/txtresolver/ConfigTextResolver.java
0 → 100644
View file @
4c2d7f44
package
com
.
ctrip
.
apollo
.
portal
.
service
.
txtresolver
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
java.util.List
;
/**
* users can modify config in text mode.so need resolve text.
*/
public
interface
ConfigTextResolver
{
TextResolverResult
resolve
(
String
configText
,
List
<
ItemDTO
>
baseItems
);
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/service/txtresolver/SimpleKVCResolver.java
0 → 100644
View file @
4c2d7f44
package
com
.
ctrip
.
apollo
.
portal
.
service
.
txtresolver
;
import
com.ctrip.apollo.core.dto.ItemChangeSets
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.core.utils.StringUtils
;
import
com.ctrip.apollo.portal.util.BeanUtils
;
import
org.springframework.stereotype.Component
;
import
java.util.List
;
import
java.util.Map
;
/**
* config item format is K:V##C
*
* @Autor lepdou
*/
@Component
public
class
SimpleKVCResolver
implements
ConfigTextResolver
{
private
static
final
String
KV_SEPARATOR
=
":"
;
private
static
final
String
VC_SEPARATOR
=
"##"
;
private
static
final
String
ITEM_SEPARATOR
=
"\n"
;
@Override
public
TextResolverResult
resolve
(
String
configText
,
List
<
ItemDTO
>
baseItems
)
{
TextResolverResult
result
=
new
TextResolverResult
();
if
(
StringUtils
.
isEmpty
(
configText
))
{
result
.
setCode
(
TextResolverResult
.
Code
.
SIMPLE_KVC_TEXT_EMPTY
);
return
result
;
}
Map
<
String
,
ItemDTO
>
baseKeyMapItem
=
BeanUtils
.
mapByKey
(
"key"
,
baseItems
);
String
[]
items
=
configText
.
split
(
ITEM_SEPARATOR
);
ItemChangeSets
changeSets
=
new
ItemChangeSets
();
int
lineCounter
=
1
;
int
kvSeparator
,
vcSeparator
;
String
key
,
value
,
comment
;
for
(
String
item
:
items
)
{
kvSeparator
=
item
.
indexOf
(
KV_SEPARATOR
);
vcSeparator
=
item
.
indexOf
(
VC_SEPARATOR
);
if
(
kvSeparator
==
-
1
||
vcSeparator
==
-
1
)
{
result
.
setCode
(
TextResolverResult
.
Code
.
SIMPLTE_KVC_INVALID_FORMAT
);
result
.
setExtensionMsg
(
" line:"
+
lineCounter
);
return
result
;
}
key
=
item
.
substring
(
0
,
kvSeparator
).
trim
();
value
=
item
.
substring
(
kvSeparator
+
1
,
vcSeparator
).
trim
();
comment
=
item
.
substring
(
vcSeparator
+
2
,
item
.
length
()).
trim
();
ItemDTO
baseItem
=
baseKeyMapItem
.
get
(
key
);
if
(
baseItem
==
null
)
{
//new item
changeSets
.
addCreatedItem
(
buildItem
(
key
,
value
,
comment
));
}
else
if
(!
value
.
equals
(
baseItem
.
getValue
())
||
!
comment
.
equals
(
baseItem
.
getComment
()))
{
//update item
changeSets
.
addupdateItem
(
buildItem
(
key
,
value
,
comment
));
}
//deleted items:items in baseItems but not in configText
baseKeyMapItem
.
remove
(
key
);
lineCounter
++;
}
//deleted items
for
(
Map
.
Entry
<
String
,
ItemDTO
>
entry
:
baseKeyMapItem
.
entrySet
())
{
changeSets
.
addDeletedItem
(
entry
.
getValue
());
}
result
.
setCode
(
TextResolverResult
.
Code
.
OK
);
result
.
setChangeSets
(
changeSets
);
return
result
;
}
private
ItemDTO
buildItem
(
String
key
,
String
value
,
String
comment
)
{
ItemDTO
item
=
new
ItemDTO
();
item
.
setKey
(
key
);
item
.
setValue
(
value
);
item
.
setComment
(
comment
);
return
item
;
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/service/txtresolver/TextResolverResult.java
0 → 100644
View file @
4c2d7f44
package
com
.
ctrip
.
apollo
.
portal
.
service
.
txtresolver
;
import
com.ctrip.apollo.core.dto.ItemChangeSets
;
public
class
TextResolverResult
{
private
Code
code
;
/**
* extension msg. for example line number.
*/
private
String
extensionMsg
=
""
;
private
ItemChangeSets
changeSets
;
public
Code
getCode
()
{
return
code
;
}
public
void
setCode
(
Code
code
)
{
this
.
code
=
code
;
}
public
String
getExtensionMsg
()
{
return
extensionMsg
;
}
public
void
setExtensionMsg
(
String
extensionMsg
)
{
this
.
extensionMsg
=
extensionMsg
;
}
public
ItemChangeSets
getChangeSets
()
{
return
changeSets
;
}
public
void
setChangeSets
(
ItemChangeSets
changeSets
)
{
this
.
changeSets
=
changeSets
;
}
public
enum
Code
{
OK
(
200
,
"success"
),
SIMPLTE_KVC_INVALID_FORMAT
(
40001
,
"item pattern must key:value##comment.pelease check!"
),
SIMPLE_KVC_TEXT_EMPTY
(
40002
,
"config text empty"
);
private
int
value
;
private
String
baseMsg
;
Code
(
int
value
,
String
msg
)
{
this
.
value
=
value
;
this
.
baseMsg
=
msg
;
}
public
int
getValue
()
{
return
value
;
}
public
void
setValue
(
int
value
)
{
this
.
value
=
value
;
}
public
String
getBaseMsg
()
{
return
baseMsg
;
}
public
void
setBaseMsg
(
String
baseMsg
)
{
this
.
baseMsg
=
baseMsg
;
}
}
}
apollo-portal/src/main/java/com/ctrip/apollo/portal/util/BeanUtils.java
0 → 100644
View file @
4c2d7f44
package
com
.
ctrip
.
apollo
.
portal
.
util
;
import
org.springframework.beans.BeanWrapper
;
import
org.springframework.beans.BeanWrapperImpl
;
import
org.springframework.util.CollectionUtils
;
import
java.lang.reflect.Field
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
public
class
BeanUtils
{
/**
* <pre>
* List<UserBean> userBeans = userDao.queryUsers();
* List<UserDTO> userDTOs = BeanUtil.batchTransform(UserDTO.class, userBeans);
* </pre>
*/
public
static
<
T
>
List
<
T
>
batchTransform
(
final
Class
<
T
>
clazz
,
List
srcList
)
{
if
(
CollectionUtils
.
isEmpty
(
srcList
))
{
return
Collections
.
EMPTY_LIST
;
}
List
<
T
>
result
=
new
ArrayList
<>(
srcList
.
size
());
for
(
Object
srcObject
:
srcList
)
{
result
.
add
(
transfrom
(
clazz
,
srcObject
));
}
return
result
;
}
/**
* 封装{@link org.springframework.beans.BeanUtils#copyProperties},惯用与直接将转换结果返回
*
* <pre>
* UserBean userBean = new UserBean("username");
* return BeanUtil.transform(UserDTO.class, userBean);
* </pre>
*/
public
static
<
T
>
T
transfrom
(
Class
<
T
>
clazz
,
Object
src
)
{
if
(
src
==
null
)
{
return
null
;
}
T
instance
=
null
;
try
{
instance
=
clazz
.
newInstance
();
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
org
.
springframework
.
beans
.
BeanUtils
.
copyProperties
(
src
,
instance
,
getNullPropertyNames
(
src
));
return
instance
;
}
static
String
[]
getNullPropertyNames
(
Object
source
)
{
final
BeanWrapper
src
=
new
BeanWrapperImpl
(
source
);
java
.
beans
.
PropertyDescriptor
[]
pds
=
src
.
getPropertyDescriptors
();
Set
<
String
>
emptyNames
=
new
HashSet
<
String
>();
for
(
java
.
beans
.
PropertyDescriptor
pd
:
pds
)
{
Object
srcValue
=
src
.
getPropertyValue
(
pd
.
getName
());
if
(
srcValue
==
null
)
{
emptyNames
.
add
(
pd
.
getName
());
}
}
String
[]
result
=
new
String
[
emptyNames
.
size
()];
return
emptyNames
.
toArray
(
result
);
}
/**
* 用于将一个列表转换为列表中的对象的某个属性映射到列表中的对象
*
* <pre>
* List<UserDTO> userList = userService.queryUsers();
* Map<Integer, userDTO> userIdToUser = BeanUtil.mapByKey("userId", Integer.class, userList,
* UserDTO.class);
* </pre>
*
* @param key 属性名
*/
public
static
<
K
,
V
>
Map
<
K
,
V
>
mapByKey
(
String
key
,
List
list
)
{
Map
<
K
,
V
>
map
=
new
HashMap
<
K
,
V
>();
if
(
CollectionUtils
.
isEmpty
(
list
))
{
return
map
;
}
try
{
Class
clazz
=
list
.
get
(
0
).
getClass
();
Field
field
=
deepFindField
(
clazz
,
key
);
field
.
setAccessible
(
true
);
for
(
Object
o
:
list
)
{
map
.
put
((
K
)
field
.
get
(
o
),
(
V
)
o
);
}
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
();
}
return
map
;
}
/**
* 根据列表里面的属性聚合
*
* <pre>
* List<ShopDTO> shopList = shopService.queryShops();
* Map<Integer, List<ShopDTO>> city2Shops = BeanUtil.aggByKeyToList("cityId", shopList);
* </pre>
*/
public
static
<
K
,
V
>
Map
<
K
,
List
<
V
>>
aggByKeyToList
(
String
key
,
List
list
)
{
Map
<
K
,
List
<
V
>>
map
=
new
HashMap
<
K
,
List
<
V
>>();
if
(
CollectionUtils
.
isEmpty
(
list
))
{
// 防止外面传入空list
return
map
;
}
try
{
Class
clazz
=
list
.
get
(
0
).
getClass
();
Field
field
=
deepFindField
(
clazz
,
key
);
field
.
setAccessible
(
true
);
for
(
Object
o
:
list
)
{
K
k
=
(
K
)
field
.
get
(
o
);
if
(
map
.
get
(
k
)
==
null
)
{
map
.
put
(
k
,
new
ArrayList
<
V
>());
}
map
.
get
(
k
).
add
((
V
)
o
);
}
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
();
}
return
map
;
}
/**
* 用于将一个对象的列表转换为列表中对象的属性集合
*
* <pre>
* List<UserDTO> userList = userService.queryUsers();
* Set<Integer> userIds = BeanUtil.toPropertySet("userId", userList);
* </pre>
*/
public
static
Set
toPropertySet
(
String
key
,
List
list
)
{
Set
set
=
new
HashSet
();
if
(
CollectionUtils
.
isEmpty
(
list
))
{
// 防止外面传入空list
return
set
;
}
try
{
Class
clazz
=
list
.
get
(
0
).
getClass
();
Field
field
=
deepFindField
(
clazz
,
key
);
if
(
field
==
null
)
{
return
set
;
}
field
.
setAccessible
(
true
);
for
(
Object
o
:
list
)
{
set
.
add
(
field
.
get
(
o
));
}
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
return
set
;
}
private
static
Field
deepFindField
(
Class
clazz
,
String
key
)
{
Field
field
=
null
;
while
(!
clazz
.
getName
().
equals
(
Object
.
class
.
getName
()))
{
try
{
field
=
clazz
.
getDeclaredField
(
key
);
if
(
field
!=
null
)
{
break
;
}
}
catch
(
Exception
e
)
{
clazz
=
clazz
.
getSuperclass
();
}
}
return
field
;
}
/**
* 获取某个对象的某个属性
*/
public
static
Object
getProperty
(
Object
obj
,
String
fieldName
)
{
try
{
Field
field
=
deepFindField
(
obj
.
getClass
(),
fieldName
);
if
(
field
!=
null
)
{
field
.
setAccessible
(
true
);
return
field
.
get
(
obj
);
}
}
catch
(
Exception
e
)
{
// ig
}
return
null
;
}
/**
* 设置某个对象的某个属性
*/
public
static
void
setProperty
(
Object
obj
,
String
fieldName
,
Object
value
)
{
try
{
Field
field
=
deepFindField
(
obj
.
getClass
(),
fieldName
);
if
(
field
!=
null
)
{
field
.
setAccessible
(
true
);
field
.
set
(
obj
,
value
);
}
}
catch
(
Exception
e
)
{
// ig
}
}
public
static
List
toPropertyList
(
String
key
,
List
list
)
{
return
new
ArrayList
(
toPropertySet
(
key
,
list
));
}
}
apollo-portal/src/main/resources/static/scripts/controller/app/AppConfigController.js
View file @
4c2d7f44
...
@@ -44,8 +44,9 @@ application_module.controller("AppConfigController",
...
@@ -44,8 +44,9 @@ application_module.controller("AppConfigController",
$scope
.
namespaces
=
result
;
$scope
.
namespaces
=
result
;
//初始化视图
//初始化视图
if
(
$scope
.
namespaces
){
if
(
$scope
.
namespaces
)
{
$scope
.
namespaces
.
forEach
(
function
(
item
){
$scope
.
namespaces
.
forEach
(
function
(
item
)
{
item
.
isModify
=
false
;
item
.
viewType
=
'table'
;
item
.
viewType
=
'table'
;
})
})
}
}
...
@@ -54,6 +55,22 @@ application_module.controller("AppConfigController",
...
@@ -54,6 +55,22 @@ application_module.controller("AppConfigController",
toastr
.
error
(
"加载配置信息出错:"
+
result
);
toastr
.
error
(
"加载配置信息出错:"
+
result
);
});
});
//更新配置
$scope
.
modifyItems
=
function
(
namespace
)
{
ConfigService
.
modify_items
(
$scope
.
appId
,
$scope
.
env
,
$scope
.
clusterName
,
namespace
.
namespace
.
namespaceName
,
namespace
.
text
).
then
(
function
(
result
)
{
if
(
result
.
code
==
200
){
toastr
.
success
(
"更新成功"
);
}
else
{
toastr
.
error
(
"更新失败. code:"
+
result
.
code
+
" msg:"
+
result
.
msg
);
}
},
function
(
result
)
{
}
);
};
/////////
/////////
$scope
.
queryOldValue
=
function
(
key
,
oldValue
)
{
$scope
.
queryOldValue
=
function
(
key
,
oldValue
)
{
$scope
.
queryKey
=
key
;
$scope
.
queryKey
=
key
;
...
@@ -64,28 +81,34 @@ application_module.controller("AppConfigController",
...
@@ -64,28 +81,34 @@ application_module.controller("AppConfigController",
}
}
};
};
$scope
.
switchView
=
function
(
namespace
,
viewType
)
{
$scope
.
switchView
=
function
(
namespace
,
viewType
)
{
if
(
'textarea'
==
viewType
)
{
if
(
'textarea'
==
viewType
)
{
namespace
.
text
=
parseTableModel2Text
(
namespace
);
namespace
.
text
=
parseTableModel2Text
(
namespace
);
}
else
if
(
'table'
==
viewType
)
{
}
}
namespace
.
viewType
=
viewType
;
namespace
.
viewType
=
viewType
;
};
};
function
parseTableModel2Text
(
namespace
){
//把表格内容解析成文本
if
(
!
namespace
.
items
){
function
parseTableModel2Text
(
namespace
)
{
if
(
!
namespace
.
items
)
{
return
"无配置信息"
;
return
"无配置信息"
;
}
}
var
result
=
""
;
var
result
=
""
;
namespace
.
items
.
forEach
(
function
(
item
){
namespace
.
items
.
forEach
(
function
(
item
)
{
if
(
item
.
modified
){
// if (item.modified) {
result
+=
"**"
;
// result += "**";
}
// }
result
+=
item
.
item
.
key
+
":"
+
item
.
item
.
value
+
" ##"
+
item
.
item
.
comment
+
"
\
n"
;
result
+=
item
.
item
.
key
+
":"
+
item
.
item
.
value
+
" ##"
+
item
.
item
.
comment
+
"
\
n"
;
});
});
return
result
;
return
result
;
}
}
//把文本内容解析成表格
}]);
}]);
apollo-portal/src/main/resources/static/scripts/services/ConfigService.js
View file @
4c2d7f44
appService
.
service
(
"ConfigService"
,
[
'$resource'
,
'$q'
,
function
(
$resource
,
$q
)
{
appService
.
service
(
"ConfigService"
,
[
'$resource'
,
'$q'
,
function
(
$resource
,
$q
)
{
var
config_source
=
$resource
(
""
,
{},
{
var
config_source
=
$resource
(
""
,
{},
{
load_all_groups
:
{
load_all_groups
:
{
method
:
'GET'
,
method
:
'GET'
,
isArray
:
true
,
isArray
:
true
,
url
:
'/apps/:appId/env/:env/clusters/:clusterName/namespaces'
url
:
'/apps/:appId/env/:env/clusters/:clusterName/namespaces'
},
modify_items
:
{
method
:
'GET'
,
isArray
:
false
,
url
:
'/apps/:appId/env/:env/clusters/:clusterName/namespaces/:namespaceName/modify'
,
params
:
{
configText
:
'@configText'
}
}
}
});
});
...
@@ -11,11 +19,27 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
...
@@ -11,11 +19,27 @@ appService.service("ConfigService", ['$resource', '$q', function ($resource, $q)
load_all_namespaces
:
function
(
appId
,
env
,
clusterName
)
{
load_all_namespaces
:
function
(
appId
,
env
,
clusterName
)
{
var
d
=
$q
.
defer
();
var
d
=
$q
.
defer
();
config_source
.
load_all_groups
({
config_source
.
load_all_groups
({
appId
:
appId
,
appId
:
appId
,
env
:
env
,
env
:
env
,
clusterName
:
clusterName
clusterName
:
clusterName
},
function
(
result
)
{
d
.
resolve
(
result
);
},
function
(
result
)
{
},
function
(
result
)
{
d
.
reject
(
result
);
});
return
d
.
promise
;
},
modify_items
:
function
(
appId
,
env
,
clusterName
,
namespaceName
,
configText
)
{
var
d
=
$q
.
defer
();
config_source
.
modify_items
({
appId
:
appId
,
env
:
env
,
clusterName
:
clusterName
,
namespaceName
:
namespaceName
,
configText
:
configText
},
function
(
result
)
{
d
.
resolve
(
result
);
d
.
resolve
(
result
);
},
function
(
result
)
{
},
function
(
result
)
{
d
.
reject
(
result
);
d
.
reject
(
result
);
});
});
...
...
apollo-portal/src/main/resources/static/views/app/index.html
View file @
4c2d7f44
...
@@ -82,7 +82,7 @@
...
@@ -82,7 +82,7 @@
<div
class=
"col-md-1 text-right"
>
<div
class=
"col-md-1 text-right"
>
<a
data-toggle=
"tooltip"
data-placement=
"top"
title=
"修改配置"
>
<a
data-toggle=
"tooltip"
data-placement=
"top"
title=
"修改配置"
ng-click=
"modifyItems(namespace)"
>
<span
class=
"glyphicon glyphicon-pencil"
aria-hidden=
"true"
></span>
<span
class=
"glyphicon glyphicon-pencil"
aria-hidden=
"true"
></span>
</a>
</a>
</div>
</div>
...
@@ -90,7 +90,11 @@
...
@@ -90,7 +90,11 @@
</header>
</header>
<div
ng-show=
"namespace.viewType == 'textarea'"
>
<div
ng-show=
"namespace.viewType == 'textarea'"
>
<textarea
class=
"form-control"
rows=
"20"
>
<textarea
class=
"form-control"
rows=
"3"
disabled
>
书写格式:key:value##comment
说明:key和value之间‘:’隔开,每个key的备注在value后面,且两个‘#’号隔开。
</textarea>
<textarea
class=
"form-control"
rows=
"20"
ng-model=
"namespace.text"
>
{{namespace.text}}
{{namespace.text}}
</textarea>
</textarea>
</div>
</div>
...
...
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