Commit 5b6dd919 authored by Jason Song's avatar Jason Song Committed by GitHub

Merge pull request #372 from nobodyiam/open-api-merge

add open api support
parents 872839c6 afa2a683
...@@ -67,7 +67,9 @@ public class NamespaceLockAspect { ...@@ -67,7 +67,9 @@ public class NamespaceLockAspect {
@Before("@annotation(PreAcquireNamespaceLock) && args(itemId, operator, ..)") @Before("@annotation(PreAcquireNamespaceLock) && args(itemId, operator, ..)")
public void requireLockAdvice(long itemId, String operator) { public void requireLockAdvice(long itemId, String operator) {
Item item = itemService.findOne(itemId); Item item = itemService.findOne(itemId);
if (item == null){
throw new BadRequestException("item not exist.");
}
acquireLock(item.getNamespaceId(), operator); acquireLock(item.getNamespaceId(), operator);
} }
......
...@@ -12,7 +12,6 @@ import org.springframework.context.ConfigurableApplicationContext; ...@@ -12,7 +12,6 @@ import org.springframework.context.ConfigurableApplicationContext;
import com.ctrip.framework.apollo.adminservice.AdminServiceApplication; import com.ctrip.framework.apollo.adminservice.AdminServiceApplication;
import com.ctrip.framework.apollo.configservice.ConfigServiceApplication; import com.ctrip.framework.apollo.configservice.ConfigServiceApplication;
import com.ctrip.framework.apollo.portal.PortalApplication;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class}) HibernateJpaAutoConfiguration.class})
......
...@@ -12,7 +12,7 @@ import org.springframework.context.ConfigurableApplicationContext; ...@@ -12,7 +12,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import com.ctrip.framework.apollo.adminservice.AdminServiceApplication; import com.ctrip.framework.apollo.adminservice.AdminServiceApplication;
import com.ctrip.framework.apollo.configservice.ConfigServiceApplication; import com.ctrip.framework.apollo.configservice.ConfigServiceApplication;
import com.ctrip.framework.apollo.portal.PortalApplication; import com.ctrip.framework.apollo.PortalApplication;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class}) HibernateJpaAutoConfiguration.class})
......
...@@ -50,7 +50,7 @@ public class AppNamespaceService { ...@@ -50,7 +50,7 @@ public class AppNamespaceService {
public List<AppNamespace> findPublicNamespacesByNames(Set<String> namespaceNames) { public List<AppNamespace> findPublicNamespacesByNames(Set<String> namespaceNames) {
if (namespaceNames == null || namespaceNames.isEmpty()) { if (namespaceNames == null || namespaceNames.isEmpty()) {
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
return appNamespaceRepository.findByNameInAndIsPublicTrue(namespaceNames); return appNamespaceRepository.findByNameInAndIsPublicTrue(namespaceNames);
...@@ -68,7 +68,7 @@ public class AppNamespaceService { ...@@ -68,7 +68,7 @@ public class AppNamespaceService {
public List<AppNamespace> findByAppIdAndNamespaces(String appId, Set<String> namespaceNames) { public List<AppNamespace> findByAppIdAndNamespaces(String appId, Set<String> namespaceNames) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(appId), "appId must not be null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(appId), "appId must not be null");
if (namespaceNames == null || namespaceNames.isEmpty()) { if (namespaceNames == null || namespaceNames.isEmpty()) {
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
return appNamespaceRepository.findByAppIdAndNameIn(appId, namespaceNames); return appNamespaceRepository.findByAppIdAndNameIn(appId, namespaceNames);
} }
......
...@@ -32,7 +32,7 @@ public class ReleaseMessageService { ...@@ -32,7 +32,7 @@ public class ReleaseMessageService {
public List<ReleaseMessage> findLatestReleaseMessagesGroupByMessages(Collection<String> messages) { public List<ReleaseMessage> findLatestReleaseMessagesGroupByMessages(Collection<String> messages) {
if (CollectionUtils.isEmpty(messages)) { if (CollectionUtils.isEmpty(messages)) {
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
List<Object[]> result = List<Object[]> result =
releaseMessageRepository.findLatestReleaseMessagesGroupByMessages(messages); releaseMessageRepository.findLatestReleaseMessagesGroupByMessages(messages);
......
...@@ -54,5 +54,9 @@ ...@@ -54,5 +54,9 @@
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
</dependency> </dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>
package com.ctrip.framework.apollo.common.controller; package com.ctrip.framework.apollo.common.controller;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
...@@ -15,6 +18,7 @@ import org.springframework.web.client.HttpStatusCodeException; ...@@ -15,6 +18,7 @@ import org.springframework.web.client.HttpStatusCodeException;
import com.ctrip.framework.apollo.common.exception.AbstractApolloHttpException; import com.ctrip.framework.apollo.common.exception.AbstractApolloHttpException;
import com.dianping.cat.Cat; import com.dianping.cat.Cat;
import java.lang.reflect.Type;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.HashMap; import java.util.HashMap;
...@@ -24,70 +28,80 @@ import javax.servlet.ServletException; ...@@ -24,70 +28,80 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_JSON;
@ControllerAdvice @ControllerAdvice
public class GlobalDefaultExceptionHandler { public class GlobalDefaultExceptionHandler {
private Gson gson = new Gson();
private static final Logger logger = LoggerFactory.getLogger(GlobalDefaultExceptionHandler.class); private static Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
//处理系统内置的Exception private static final Logger logger = LoggerFactory.getLogger(GlobalDefaultExceptionHandler.class);
@ExceptionHandler(Throwable.class)
public ResponseEntity<Map<String, Object>> exception(HttpServletRequest request, Throwable ex) { //处理系统内置的Exception
return handleError(request, INTERNAL_SERVER_ERROR, ex); @ExceptionHandler(Throwable.class)
} public ResponseEntity<Map<String, Object>> exception(HttpServletRequest request, Throwable ex) {
return handleError(request, INTERNAL_SERVER_ERROR, ex);
@ExceptionHandler({HttpRequestMethodNotSupportedException.class, HttpMediaTypeException.class}) }
public ResponseEntity<Map<String, Object>> badRequest(HttpServletRequest request,
ServletException ex) { @ExceptionHandler({HttpRequestMethodNotSupportedException.class, HttpMediaTypeException.class})
return handleError(request, BAD_REQUEST, ex); public ResponseEntity<Map<String, Object>> badRequest(HttpServletRequest request,
} ServletException ex) {
return handleError(request, BAD_REQUEST, ex);
@ExceptionHandler(HttpStatusCodeException.class) }
public ResponseEntity<Map<String, Object>> restTemplateException(HttpServletRequest request,
HttpStatusCodeException ex) { @ExceptionHandler(HttpStatusCodeException.class)
return handleError(request, ex.getStatusCode(), ex); public ResponseEntity<Map<String, Object>> restTemplateException(HttpServletRequest request,
} HttpStatusCodeException ex) {
return handleError(request, ex.getStatusCode(), ex);
@ExceptionHandler(AccessDeniedException.class) }
public ResponseEntity<Map<String, Object>> accessDeny(HttpServletRequest request,
AccessDeniedException ex) { @ExceptionHandler(AccessDeniedException.class)
return handleError(request, UNAUTHORIZED, ex); public ResponseEntity<Map<String, Object>> accessDeny(HttpServletRequest request,
} AccessDeniedException ex) {
return handleError(request, FORBIDDEN, ex);
//处理自定义Exception }
@ExceptionHandler({AbstractApolloHttpException.class})
public ResponseEntity<Map<String, Object>> badRequest(HttpServletRequest request, AbstractApolloHttpException ex) { //处理自定义Exception
return handleError(request, ex); @ExceptionHandler({AbstractApolloHttpException.class})
} public ResponseEntity<Map<String, Object>> badRequest(HttpServletRequest request, AbstractApolloHttpException ex) {
return handleError(request, ex);
}
private ResponseEntity<Map<String, Object>> handleError(HttpServletRequest request,
AbstractApolloHttpException ex) {
return handleError(request, ex.getHttpStatus(), ex); private ResponseEntity<Map<String, Object>> handleError(HttpServletRequest request,
} AbstractApolloHttpException ex) {
return handleError(request, ex.getHttpStatus(), ex);
}
private ResponseEntity<Map<String, Object>> handleError(HttpServletRequest request,
HttpStatus status, Throwable ex) {
String message = ex.getMessage(); private ResponseEntity<Map<String, Object>> handleError(HttpServletRequest request,
HttpStatus status, Throwable ex) {
logger.error(message, ex); String message = ex.getMessage();
Cat.logError(ex);
logger.error(message, ex);
Map<String, Object> errorAttributes = new HashMap<>(); Cat.logError(ex);
errorAttributes.put("status", status.value());
errorAttributes.put("message", message); Map<String, Object> errorAttributes = new HashMap<>();
errorAttributes.put("timestamp",
LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); //如果是admin server引起的异常,则显示内部的异常信息
errorAttributes.put("exception", ex.getClass().getName()); if (ex instanceof HttpStatusCodeException){
errorAttributes = gson.fromJson(((HttpStatusCodeException)ex).getResponseBodyAsString(), mapType);
HttpHeaders headers = new HttpHeaders(); status = ((HttpStatusCodeException)ex).getStatusCode();
headers.setContentType(APPLICATION_JSON); } else {
return new ResponseEntity<>(errorAttributes, headers, status); errorAttributes.put("status", status.value());
} errorAttributes.put("message", message);
errorAttributes.put("timestamp",
LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
errorAttributes.put("exception", ex.getClass().getName());
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(APPLICATION_JSON);
return new ResponseEntity<>(errorAttributes, headers, status);
}
} }
...@@ -14,15 +14,15 @@ public class RequestPrecondition { ...@@ -14,15 +14,15 @@ public class RequestPrecondition {
private static String ILLEGAL_NUMBER = "number should be positive"; private static String ILLEGAL_NUMBER = "number should be positive";
public static void checkArgument(String... args) { public static void checkArgumentsNotEmpty(String... args) {
checkArgument(!StringUtils.isContainEmpty(args), CONTAIN_EMPTY_ARGUMENT); checkArguments(!StringUtils.isContainEmpty(args), CONTAIN_EMPTY_ARGUMENT);
} }
public static void checkModel(boolean valid){ public static void checkModel(boolean valid){
checkArgument(valid, ILLEGAL_MODEL); checkArguments(valid, ILLEGAL_MODEL);
} }
public static void checkArgument(boolean expression, Object errorMessage) { public static void checkArguments(boolean expression, Object errorMessage) {
if (!expression) { if (!expression) {
throw new BadRequestException(String.valueOf(errorMessage)); throw new BadRequestException(String.valueOf(errorMessage));
} }
...@@ -36,6 +36,14 @@ public class RequestPrecondition { ...@@ -36,6 +36,14 @@ public class RequestPrecondition {
} }
} }
public static void checkNumberPositive(long... args){
for (long num: args){
if (num <= 0){
throw new BadRequestException(ILLEGAL_NUMBER);
}
}
}
public static void checkNumberNotNegative(int... args){ public static void checkNumberNotNegative(int... args){
for (int num: args){ for (int num: args){
if (num < 0){ if (num < 0){
......
package com.ctrip.framework.apollo.core.enums; package com.ctrip.framework.apollo.core.enums;
import com.google.common.base.Preconditions;
/** /**
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
public enum Env{ public enum Env{
LOCAL, DEV, FWS, FAT, UAT, LPT, PRO, TOOLS LOCAL, DEV, FWS, FAT, UAT, LPT, PRO, TOOLS;
public static Env fromString(String env) {
Env environment = EnvUtils.transformEnv(env);
Preconditions.checkArgument(environment != null, String.format("Env %s is invalid", env));
return environment;
}
} }
package com.ctrip.framework.apollo.portal; package com.ctrip.framework.apollo;
import com.ctrip.framework.apollo.common.ApolloCommonConfig; import com.ctrip.framework.apollo.common.ApolloCommonConfig;
...@@ -16,8 +16,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; ...@@ -16,8 +16,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration @Configuration
@EnableAutoConfiguration @EnableAutoConfiguration
@EnableTransactionManagement @EnableTransactionManagement
@ComponentScan(basePackageClasses = {ApolloCommonConfig.class, @ComponentScan(basePackageClasses = {ApolloCommonConfig.class, PortalApplication.class})
PortalApplication.class})
public class PortalApplication { public class PortalApplication {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
......
package com.ctrip.framework.apollo.openapi.auth;
import com.ctrip.framework.apollo.openapi.service.ConsumerRolePermissionService;
import com.ctrip.framework.apollo.openapi.util.ConsumerAuthUtil;
import com.ctrip.framework.apollo.portal.constant.PermissionType;
import com.ctrip.framework.apollo.portal.util.RoleUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class ConsumerPermissionValidator {
@Autowired
private ConsumerRolePermissionService permissionService;
@Autowired
private ConsumerAuthUtil consumerAuthUtil;
public boolean hasModifyNamespacePermission(HttpServletRequest request, String appId, String
namespaceName) {
return permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request),
PermissionType.MODIFY_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
}
public boolean hasReleaseNamespacePermission(HttpServletRequest request, String appId, String
namespaceName) {
return permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request),
PermissionType.RELEASE_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
}
}
package com.ctrip.framework.apollo.openapi.dto;
import com.ctrip.framework.apollo.common.dto.BaseDTO;
public class OpenItemDTO extends BaseDTO {
private long id;
private String key;
private String value;
private String comment;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
package com.ctrip.framework.apollo.openapi.dto;
import com.ctrip.framework.apollo.common.dto.BaseDTO;
import java.util.List;
public class OpenNamespaceDTO extends BaseDTO {
private String appId;
private String clusterName;
private String namespaceName;
private String comment;
private String format;
private boolean isPublic;
private List<OpenItemDTO> items;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
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;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public boolean isPublic() {
return isPublic;
}
public void setPublic(boolean aPublic) {
isPublic = aPublic;
}
public List<OpenItemDTO> getItems() {
return items;
}
public void setItems(List<OpenItemDTO> items) {
this.items = items;
}
}
package com.ctrip.framework.apollo.openapi.dto;
public class OpenNamespaceLockDTO {
private String namespaceName;
private boolean isLocked;
private String lockedBy;
public String getNamespaceName() {
return namespaceName;
}
public void setNamespaceName(String namespaceName) {
this.namespaceName = namespaceName;
}
public boolean isLocked() {
return isLocked;
}
public void setLocked(boolean locked) {
isLocked = locked;
}
public String getLockedBy() {
return lockedBy;
}
public void setLockedBy(String lockedBy) {
this.lockedBy = lockedBy;
}
}
package com.ctrip.framework.apollo.openapi.dto;
import com.ctrip.framework.apollo.common.dto.BaseDTO;
import java.util.Map;
public class OpenReleaseDTO extends BaseDTO {
private String appId;
private String clusterName;
private String namespaceName;
private String name;
private Map<String, String> configurations;
private String comment;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
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;
}
public Map<String, String> getConfigurations() {
return configurations;
}
public void setConfigurations(Map<String, String> configurations) {
this.configurations = configurations;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
package com.ctrip.framework.apollo.openapi.entity;
import com.ctrip.framework.apollo.common.entity.BaseEntity;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "Consumer")
@SQLDelete(sql = "Update Consumer set isDeleted = 1 where id = ?")
@Where(clause = "isDeleted = 0")
public class Consumer extends BaseEntity {
@Column(name = "Name", nullable = false)
private String name;
@Column(name = "AppId", nullable = false)
private String appId;
@Column(name = "OrgId", nullable = false)
private String orgId;
@Column(name = "OrgName", nullable = false)
private String orgName;
@Column(name = "OwnerName", nullable = false)
private String ownerName;
@Column(name = "OwnerEmail", nullable = false)
private String ownerEmail;
public String getAppId() {
return appId;
}
public String getName() {
return name;
}
public String getOrgId() {
return orgId;
}
public String getOrgName() {
return orgName;
}
public String getOwnerEmail() {
return ownerEmail;
}
public String getOwnerName() {
return ownerName;
}
public void setAppId(String appId) {
this.appId = appId;
}
public void setName(String name) {
this.name = name;
}
public void setOrgId(String orgId) {
this.orgId = orgId;
}
public void setOrgName(String orgName) {
this.orgName = orgName;
}
public void setOwnerEmail(String ownerEmail) {
this.ownerEmail = ownerEmail;
}
public void setOwnerName(String ownerName) {
this.ownerName = ownerName;
}
@Override
public String toString() {
return toStringHelper().add("name", name).add("appId", appId)
.add("orgId", orgId)
.add("orgName", orgName)
.add("ownerName", ownerName)
.add("ownerEmail", ownerEmail).toString();
}
}
package com.ctrip.framework.apollo.openapi.entity;
import com.ctrip.framework.apollo.common.entity.BaseEntity;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Entity
@Table(name = "ConsumerRole")
@SQLDelete(sql = "Update ConsumerRole set isDeleted = 1 where id = ?")
@Where(clause = "isDeleted = 0")
public class ConsumerRole extends BaseEntity {
@Column(name = "ConsumerId", nullable = false)
private long consumerId;
@Column(name = "RoleId", nullable = false)
private long roleId;
public long getConsumerId() {
return consumerId;
}
public void setConsumerId(long consumerId) {
this.consumerId = consumerId;
}
public long getRoleId() {
return roleId;
}
public void setRoleId(long roleId) {
this.roleId = roleId;
}
@Override
public String toString() {
return toStringHelper().add("consumerId", consumerId).add("roleId", roleId).toString();
}
}
package com.ctrip.framework.apollo.openapi.entity;
import com.ctrip.framework.apollo.common.entity.BaseEntity;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Entity
@Table(name = "ConsumerToken")
@SQLDelete(sql = "Update ConsumerToken set isDeleted = 1 where id = ?")
@Where(clause = "isDeleted = 0")
public class ConsumerToken extends BaseEntity {
@Column(name = "ConsumerId", nullable = false)
private long consumerId;
@Column(name = "token", nullable = false)
private String token;
@Column(name = "Expires", nullable = false)
private Date expires;
public long getConsumerId() {
return consumerId;
}
public void setConsumerId(long consumerId) {
this.consumerId = consumerId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public Date getExpires() {
return expires;
}
public void setExpires(Date expires) {
this.expires = expires;
}
@Override
public String toString() {
return toStringHelper().add("consumerId", consumerId).add("token", token)
.add("expires", expires).toString();
}
}
package com.ctrip.framework.apollo.openapi.filter;
import com.ctrip.framework.apollo.openapi.util.ConsumerAuthUtil;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ConsumerAuthenticationFilter implements Filter {
private ConsumerAuthUtil consumerAuthUtil;
public ConsumerAuthenticationFilter(ConsumerAuthUtil consumerAuthUtil) {
this.consumerAuthUtil = consumerAuthUtil;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//nothing
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws
IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
String token = request.getHeader("Authorization");
Long consumerId = consumerAuthUtil.getConsumerId(token);
if (consumerId == null) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
return;
}
consumerAuthUtil.storeConsumerId(request, consumerId);
chain.doFilter(req, resp);
}
@Override
public void destroy() {
//nothing
}
}
package com.ctrip.framework.apollo.openapi.repository;
import com.ctrip.framework.apollo.openapi.entity.Consumer;
import org.springframework.data.repository.PagingAndSortingRepository;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public interface ConsumerRepository extends PagingAndSortingRepository<Consumer, Long> {
}
package com.ctrip.framework.apollo.openapi.repository;
import com.ctrip.framework.apollo.openapi.entity.ConsumerRole;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public interface ConsumerRoleRepository extends PagingAndSortingRepository<ConsumerRole, Long> {
/**
* find consumer roles by userId
*
* @param consumerId consumer id
*/
List<ConsumerRole> findByConsumerId(long consumerId);
/**
* find consumer roles by roleId
*/
List<ConsumerRole> findByRoleId(long roleId);
}
package com.ctrip.framework.apollo.openapi.repository;
import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.Date;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public interface ConsumerTokenRepository extends PagingAndSortingRepository<ConsumerToken, Long> {
/**
* find consumer token by token
*
* @param token the token
* @param validDate the date when the token is valid
*/
ConsumerToken findTopByTokenAndExpiresAfter(String token, Date validDate);
}
package com.ctrip.framework.apollo.openapi.service;
import com.google.common.collect.FluentIterable;
import com.ctrip.framework.apollo.openapi.entity.ConsumerRole;
import com.ctrip.framework.apollo.openapi.repository.ConsumerRoleRepository;
import com.ctrip.framework.apollo.portal.entity.po.Permission;
import com.ctrip.framework.apollo.portal.entity.po.RolePermission;
import com.ctrip.framework.apollo.portal.repository.PermissionRepository;
import com.ctrip.framework.apollo.portal.repository.RolePermissionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Set;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Service
public class ConsumerRolePermissionService {
@Autowired
private PermissionRepository permissionRepository;
@Autowired
private ConsumerRoleRepository consumerRoleRepository;
@Autowired
private RolePermissionRepository rolePermissionRepository;
/**
* Check whether user has the permission
*/
public boolean consumerHasPermission(long consumerId, String permissionType, String targetId) {
Permission permission =
permissionRepository.findTopByPermissionTypeAndTargetId(permissionType, targetId);
if (permission == null) {
return false;
}
List<ConsumerRole> consumerRoles = consumerRoleRepository.findByConsumerId(consumerId);
if (CollectionUtils.isEmpty(consumerRoles)) {
return false;
}
Set<Long> roleIds =
FluentIterable.from(consumerRoles).transform(consumerRole -> consumerRole.getRoleId())
.toSet();
List<RolePermission> rolePermissions = rolePermissionRepository.findByRoleIdIn(roleIds);
if (CollectionUtils.isEmpty(rolePermissions)) {
return false;
}
for (RolePermission rolePermission : rolePermissions) {
if (rolePermission.getPermissionId() == permission.getId()) {
return true;
}
}
return false;
}
}
package com.ctrip.framework.apollo.openapi.service;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.hash.Hashing;
import com.ctrip.framework.apollo.openapi.entity.Consumer;
import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
import com.ctrip.framework.apollo.openapi.repository.ConsumerRepository;
import com.ctrip.framework.apollo.openapi.repository.ConsumerTokenRepository;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import org.apache.commons.lang.time.FastDateFormat;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Service
public class ConsumerService implements InitializingBean {
static final String TOKEN_SALT_KEY = "consumer.token.salt";
private static final FastDateFormat TIMESTAMP_FORMAT = FastDateFormat.getInstance
("yyyyMMddHHmmss");
private static final Joiner KEY_JOINER = Joiner.on("|");
@Autowired
private ConsumerTokenRepository consumerTokenRepository;
@Autowired
private ConsumerRepository consumerRepository;
@Autowired
private ServerConfigService serverConfigService;
private String consumerTokenSalt;
public Long getConsumerIdByToken(String token) {
if (Strings.isNullOrEmpty(token)) {
return null;
}
ConsumerToken consumerToken = consumerTokenRepository.findTopByTokenAndExpiresAfter(token,
new Date());
return consumerToken == null ? null : consumerToken.getConsumerId();
}
public Consumer getConsumerByConsumerId(long consumerId) {
return consumerRepository.findOne(consumerId);
}
public void generateAndEnrichConsumerToken(ConsumerToken consumerToken) {
Consumer consumer = getConsumerByConsumerId(consumerToken.getConsumerId());
Preconditions.checkState(consumer != null, String.format("Consumer with id: %d not found!",
consumerToken.getConsumerId()));
if (consumerToken.getDataChangeCreatedTime() == null) {
consumerToken.setDataChangeCreatedTime(new Date());
}
consumerToken.setToken(generateConsumerToken(consumer.getAppId(), consumerToken
.getDataChangeCreatedTime(), consumerTokenSalt));
}
@Transactional
public ConsumerToken createConsumerToken(ConsumerToken entity) {
entity.setId(0); //for protection
return consumerTokenRepository.save(entity);
}
String generateConsumerToken(String consumerAppId, Date generationTime, String
consumerTokenSalt) {
return Hashing.sha1().hashString(KEY_JOINER.join(consumerAppId, TIMESTAMP_FORMAT.format
(generationTime), consumerTokenSalt), Charsets.UTF_8).toString();
}
@Override
public void afterPropertiesSet() throws Exception {
consumerTokenSalt = serverConfigService.getValue(TOKEN_SALT_KEY, "apollo-portal");
}
}
package com.ctrip.framework.apollo.openapi.util;
import com.ctrip.framework.apollo.openapi.service.ConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Service
public class ConsumerAuthUtil {
static final String CONSUMER_ID = "ApolloConsumerId";
@Autowired
private ConsumerService consumerService;
public Long getConsumerId(String token) {
return consumerService.getConsumerIdByToken(token);
}
public void storeConsumerId(HttpServletRequest request, Long consumerId) {
request.setAttribute(CONSUMER_ID, consumerId);
}
public long retrieveConsumerId(HttpServletRequest request) {
Object value = request.getAttribute(CONSUMER_ID);
try {
return Long.parseLong(value.toString());
} catch (Throwable ex) {
throw new IllegalStateException("No consumer id!", ex);
}
}
}
package com.ctrip.framework.apollo.openapi.util;
import com.google.common.base.Preconditions;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceLockDTO;
import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceLockDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenReleaseDTO;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceVO;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class OpenApiBeanUtils {
private static Gson gson = new Gson();
private static Type type = new TypeToken<Map<String, String>>() {
}.getType();
public static OpenItemDTO transformFromItemDTO(ItemDTO item) {
Preconditions.checkArgument(item != null);
return BeanUtils.transfrom(OpenItemDTO.class, item);
}
public static ItemDTO transformToItemDTO(OpenItemDTO openItemDTO) {
Preconditions.checkArgument(openItemDTO != null);
return BeanUtils.transfrom(ItemDTO.class, openItemDTO);
}
public static OpenReleaseDTO transformFromReleaseDTO(ReleaseDTO release) {
Preconditions.checkArgument(release != null);
OpenReleaseDTO openReleaseDTO = BeanUtils.transfrom(OpenReleaseDTO.class, release);
Map<String, String> configs = gson.fromJson(release.getConfigurations(), type);
openReleaseDTO.setConfigurations(configs);
return openReleaseDTO;
}
public static OpenNamespaceDTO transformFromNamespaceVO(NamespaceVO namespaceVO) {
Preconditions.checkArgument(namespaceVO != null);
OpenNamespaceDTO openNamespaceDTO = BeanUtils.transfrom(OpenNamespaceDTO.class, namespaceVO
.getBaseInfo());
//app namespace info
openNamespaceDTO.setFormat(namespaceVO.getFormat());
openNamespaceDTO.setComment(namespaceVO.getComment());
openNamespaceDTO.setPublic(namespaceVO.isPublic());
//items
List<OpenItemDTO> items = new LinkedList<>();
List<NamespaceVO.ItemVO> itemVOs = namespaceVO.getItems();
if (!CollectionUtils.isEmpty(itemVOs)) {
items.addAll(itemVOs.stream().map(itemVO -> transformFromItemDTO(itemVO.getItem())).collect
(Collectors.toList()));
}
openNamespaceDTO.setItems(items);
return openNamespaceDTO;
}
public static List<OpenNamespaceDTO> batchTransformFromNamespaceVOs(List<NamespaceVO>
namespaceVOs) {
if (CollectionUtils.isEmpty(namespaceVOs)) {
return Collections.emptyList();
}
List<OpenNamespaceDTO> openNamespaceDTOs =
namespaceVOs.stream().map(OpenApiBeanUtils::transformFromNamespaceVO)
.collect(Collectors.toCollection(LinkedList::new));
return openNamespaceDTOs;
}
public static OpenNamespaceLockDTO transformFromNamespaceLockDTO(String namespaceName,
NamespaceLockDTO
namespaceLock) {
OpenNamespaceLockDTO lock = new OpenNamespaceLockDTO();
lock.setNamespaceName(namespaceName);
if (namespaceLock == null) {
lock.setLocked(false);
} else {
lock.setLocked(true);
lock.setLockedBy(namespaceLock.getDataChangeCreatedBy());
}
return lock;
}
}
package com.ctrip.framework.apollo.openapi.v1.controller;
import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
import com.ctrip.framework.apollo.openapi.util.OpenApiBeanUtils;
import com.ctrip.framework.apollo.portal.service.ItemService;
import com.ctrip.framework.apollo.portal.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
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 javax.servlet.http.HttpServletRequest;
@RestController("openapiItemController")
@RequestMapping("/openapi/v1/envs/{env}")
public class ItemController {
@Autowired
private ItemService itemService;
@Autowired
private UserService userService;
@PreAuthorize(value = "@consumerPermissionValidator.hasModifyNamespacePermission(#request, #appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items", method = RequestMethod.POST)
public OpenItemDTO createItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String
namespaceName,
@RequestBody OpenItemDTO item, HttpServletRequest request) {
RequestPrecondition.checkArguments(
!StringUtils.isContainEmpty(item.getKey(), item.getValue(), item.getDataChangeCreatedBy()),
"key,value,dataChangeCreatedBy 字段不能为空");
if (userService.findByUserId(item.getDataChangeCreatedBy()) == null) {
throw new BadRequestException("用户不存在.");
}
ItemDTO toCreate = OpenApiBeanUtils.transformToItemDTO(item);
//protect
toCreate.setLineNum(0);
toCreate.setId(0);
toCreate.setDataChangeLastModifiedBy(toCreate.getDataChangeCreatedBy());
ItemDTO createdItem = itemService.createItem(appId, Env.fromString(env),
clusterName, namespaceName, toCreate);
return OpenApiBeanUtils.transformFromItemDTO(createdItem);
}
@PreAuthorize(value = "@consumerPermissionValidator.hasModifyNamespacePermission(#request, #appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}", method = RequestMethod.PUT)
public void updateItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
@PathVariable long itemId, @RequestBody OpenItemDTO item,
HttpServletRequest request) {
RequestPrecondition.checkArguments(item != null && item.getId() > 0 && itemId == item.getId(),
"item data error");
RequestPrecondition.checkArguments(
!StringUtils.isContainEmpty(item.getKey(), item.getValue(), item
.getDataChangeLastModifiedBy()),
"key,value,dataChangeLastModifiedBy 字段不能为空");
if (userService.findByUserId(item.getDataChangeLastModifiedBy()) == null) {
throw new BadRequestException("用户不存在.");
}
ItemDTO toUpdateItem = itemService.loadItem(Env.fromString(env), itemId);
if (toUpdateItem == null) {
throw new BadRequestException("item not exist");
}
//protect. only value,comment,lastModifiedBy can be modified
toUpdateItem.setComment(item.getComment());
toUpdateItem.setValue(item.getValue());
toUpdateItem.setDataChangeLastModifiedBy(item.getDataChangeLastModifiedBy());
itemService.updateItem(appId, Env.fromString(env), clusterName, namespaceName,
toUpdateItem);
}
@PreAuthorize(value = "@consumerPermissionValidator.hasModifyNamespacePermission(#request, #appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}", method = RequestMethod.DELETE)
public void deleteItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
@PathVariable long itemId, @RequestParam String operator,
HttpServletRequest request) {
if (userService.findByUserId(operator) == null) {
throw new BadRequestException("用户不存在.");
}
itemService.deleteItem(Env.fromString(env), itemId, operator);
}
}
package com.ctrip.framework.apollo.openapi.v1.controller;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceLockDTO;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceLockDTO;
import com.ctrip.framework.apollo.openapi.util.OpenApiBeanUtils;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceVO;
import com.ctrip.framework.apollo.portal.service.NamespaceLockService;
import com.ctrip.framework.apollo.portal.service.NamespaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
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("openapiNamespaceController")
@RequestMapping("/openapi/v1/envs/{env}")
public class NamespaceController {
@Autowired
private NamespaceLockService namespaceLockService;
@Autowired
private NamespaceService namespaceService;
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces", method = RequestMethod.GET)
public List<OpenNamespaceDTO> findNamespaces(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName) {
return OpenApiBeanUtils
.batchTransformFromNamespaceVOs(namespaceService.findNamespaces(appId, Env
.fromString(env), clusterName));
}
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName:.+}", method = RequestMethod.GET)
public OpenNamespaceDTO loadNamespace(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String
namespaceName) {
NamespaceVO namespaceVO = namespaceService.loadNamespace(appId, Env.fromString
(env), clusterName, namespaceName);
if (namespaceVO == null) {
return null;
}
return OpenApiBeanUtils.transformFromNamespaceVO(namespaceVO);
}
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/lock", method = RequestMethod.GET)
public OpenNamespaceLockDTO getNamespaceLock(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable
String namespaceName) {
NamespaceDTO namespace = namespaceService.loadNamespaceBaseInfo(appId, Env
.fromString(env), clusterName, namespaceName);
NamespaceLockDTO lockDTO = namespaceLockService.getNamespaceLock(appId, Env
.fromString(env), clusterName, namespaceName);
return OpenApiBeanUtils.transformFromNamespaceLockDTO(namespace.getNamespaceName(), lockDTO);
}
}
package com.ctrip.framework.apollo.openapi.v1.controller;
import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.openapi.dto.OpenReleaseDTO;
import com.ctrip.framework.apollo.openapi.util.OpenApiBeanUtils;
import com.ctrip.framework.apollo.portal.entity.form.NamespaceReleaseModel;
import com.ctrip.framework.apollo.portal.service.ReleaseService;
import com.ctrip.framework.apollo.portal.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
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 javax.servlet.http.HttpServletRequest;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkModel;
@RestController("openapiReleaseController")
@RequestMapping("/openapi/v1/envs/{env}")
public class ReleaseController {
@Autowired
private ReleaseService releaseService;
@Autowired
private UserService userService;
@PreAuthorize(value = "@consumerPermissionValidator.hasReleaseNamespacePermission(#request, #appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases", method = RequestMethod.POST)
public OpenReleaseDTO createRelease(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String
namespaceName,
@RequestBody NamespaceReleaseModel model,
HttpServletRequest request) {
checkModel(model != null);
RequestPrecondition.checkArguments(!StringUtils.isContainEmpty(model.getReleasedBy(), model
.getReleaseTitle()),
"releaseTitle and releaseBy can not be empty");
if (userService.findByUserId(model.getReleasedBy()) == null) {
throw new BadRequestException("用户不存在.");
}
model.setAppId(appId);
model.setEnv(Env.fromString(env).toString());
model.setClusterName(clusterName);
model.setNamespaceName(namespaceName);
return OpenApiBeanUtils.transformFromReleaseDTO(releaseService.createRelease(model));
}
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases/latest", method = RequestMethod.GET)
public OpenReleaseDTO loadLatestActiveRelease(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable
String namespaceName) {
ReleaseDTO releaseDTO = releaseService.loadLatestRelease(appId, Env.fromString
(env), clusterName, namespaceName);
if (releaseDTO == null) {
return null;
}
return OpenApiBeanUtils.transformFromReleaseDTO(releaseDTO);
}
}
package com.ctrip.framework.apollo.portal; package com.ctrip.framework.apollo.portal;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.service.ServerConfigService; import com.ctrip.framework.apollo.portal.service.ServerConfigService;
...@@ -67,11 +66,11 @@ public class PortalSettings { ...@@ -67,11 +66,11 @@ public class PortalSettings {
healthCheckService healthCheckService
.scheduleWithFixedDelay(new HealthCheckTask(applicationContext), 1000, HEALTH_CHECK_INTERVAL, .scheduleWithFixedDelay(new HealthCheckTask(applicationContext), 1000, HEALTH_CHECK_INTERVAL,
TimeUnit.MILLISECONDS); TimeUnit.MILLISECONDS);
} }
public List<Env> getAllEnvs(){ public List<Env> getAllEnvs() {
return allEnvs; return allEnvs;
} }
......
package com.ctrip.framework.apollo.portal.api; package com.ctrip.framework.apollo.portal.api;
import com.ctrip.framework.apollo.common.dto.AppNamespaceDTO;
import com.ctrip.framework.apollo.common.dto.CommitDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceLockDTO;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.common.dto.AppDTO; import com.ctrip.framework.apollo.common.dto.AppDTO;
import com.ctrip.framework.apollo.common.dto.AppNamespaceDTO;
import com.ctrip.framework.apollo.common.dto.ClusterDTO; import com.ctrip.framework.apollo.common.dto.ClusterDTO;
import com.ctrip.framework.apollo.common.dto.CommitDTO;
import com.ctrip.framework.apollo.common.dto.ItemChangeSets; import com.ctrip.framework.apollo.common.dto.ItemChangeSets;
import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceLockDTO;
import com.ctrip.framework.apollo.common.dto.ReleaseDTO; import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
import com.ctrip.framework.apollo.core.enums.Env;
import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.Health;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
...@@ -53,8 +53,8 @@ public class AdminServiceAPI { ...@@ -53,8 +53,8 @@ public class AdminServiceAPI {
public List<NamespaceDTO> findNamespaceByCluster(String appId, Env env, String clusterName) { public List<NamespaceDTO> findNamespaceByCluster(String appId, Env env, String clusterName) {
NamespaceDTO[] namespaceDTOs = restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces", NamespaceDTO[] namespaceDTOs = restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces",
NamespaceDTO[].class, appId, NamespaceDTO[].class, appId,
clusterName); clusterName);
return Arrays.asList(namespaceDTOs); return Arrays.asList(namespaceDTOs);
} }
...@@ -62,7 +62,7 @@ public class AdminServiceAPI { ...@@ -62,7 +62,7 @@ public class AdminServiceAPI {
String namespaceName) { String namespaceName) {
NamespaceDTO dto = NamespaceDTO dto =
restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}", restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}",
NamespaceDTO.class, appId, clusterName, namespaceName); NamespaceDTO.class, appId, clusterName, namespaceName);
return dto; return dto;
} }
...@@ -70,7 +70,7 @@ public class AdminServiceAPI { ...@@ -70,7 +70,7 @@ public class AdminServiceAPI {
public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace) { public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace) {
return restTemplate return restTemplate
.post(env, "apps/{appId}/clusters/{clusterName}/namespaces", namespace, NamespaceDTO.class, .post(env, "apps/{appId}/clusters/{clusterName}/namespaces", namespace, NamespaceDTO.class,
namespace.getAppId(), namespace.getClusterName()); namespace.getAppId(), namespace.getClusterName());
} }
public AppNamespaceDTO createAppNamespace(Env env, AppNamespaceDTO appNamespace) { public AppNamespaceDTO createAppNamespace(Env env, AppNamespaceDTO appNamespace) {
...@@ -86,26 +86,29 @@ public class AdminServiceAPI { ...@@ -86,26 +86,29 @@ public class AdminServiceAPI {
public List<ItemDTO> findItems(String appId, Env env, String clusterName, String namespaceName) { public List<ItemDTO> findItems(String appId, Env env, String clusterName, String namespaceName) {
ItemDTO[] itemDTOs = ItemDTO[] itemDTOs =
restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items", restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items",
ItemDTO[].class, appId, clusterName, namespaceName); ItemDTO[].class, appId, clusterName, namespaceName);
return Arrays.asList(itemDTOs); return Arrays.asList(itemDTOs);
} }
public ItemDTO loadItem(Env env, long itemId) {
return restTemplate.get(env, "/items/{itemId}", ItemDTO.class, itemId);
}
public void updateItemsByChangeSet(String appId, Env env, String clusterName, String namespace, public void updateItemsByChangeSet(String appId, Env env, String clusterName, String namespace,
ItemChangeSets changeSets) { ItemChangeSets changeSets) {
restTemplate.post(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/itemset", restTemplate.post(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/itemset",
changeSets, Void.class, appId, clusterName, namespace); changeSets, Void.class, appId, clusterName, namespace);
} }
public void updateItem(String appId, Env env, String clusterName, String namespace, long itemId, ItemDTO item) { public void updateItem(String appId, Env env, String clusterName, String namespace, long itemId, ItemDTO item) {
restTemplate.put(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}", restTemplate.put(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}",
item, appId, clusterName, namespace, itemId); item, appId, clusterName, namespace, itemId);
} }
public ItemDTO createItem(String appId, Env env, String clusterName, String namespace, ItemDTO item) { public ItemDTO createItem(String appId, Env env, String clusterName, String namespace, ItemDTO item) {
return restTemplate.post(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items", return restTemplate.post(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items",
item, ItemDTO.class, appId, clusterName, namespace) item, ItemDTO.class, appId, clusterName, namespace);
;
} }
public void deleteItem(Env env, long itemId, String operator) { public void deleteItem(Env env, long itemId, String operator) {
...@@ -119,25 +122,25 @@ public class AdminServiceAPI { ...@@ -119,25 +122,25 @@ public class AdminServiceAPI {
public List<ClusterDTO> findClustersByApp(String appId, Env env) { public List<ClusterDTO> findClustersByApp(String appId, Env env) {
ClusterDTO[] clusterDTOs = restTemplate.get(env, "apps/{appId}/clusters", ClusterDTO[].class, ClusterDTO[] clusterDTOs = restTemplate.get(env, "apps/{appId}/clusters", ClusterDTO[].class,
appId); appId);
return Arrays.asList(clusterDTOs); return Arrays.asList(clusterDTOs);
} }
public ClusterDTO loadCluster(String appId, Env env, String clusterName) { public ClusterDTO loadCluster(String appId, Env env, String clusterName) {
return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}", ClusterDTO.class, return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}", ClusterDTO.class,
appId, clusterName); appId, clusterName);
} }
public boolean isClusterUnique(String appId, Env env, String clusterName) { public boolean isClusterUnique(String appId, Env env, String clusterName) {
return restTemplate return restTemplate
.get(env, "apps/{appId}/cluster/{clusterName}/unique", Boolean.class, .get(env, "apps/{appId}/cluster/{clusterName}/unique", Boolean.class,
appId, clusterName); appId, clusterName);
} }
public ClusterDTO create(Env env, ClusterDTO cluster) { public ClusterDTO create(Env env, ClusterDTO cluster) {
return restTemplate.post(env, "apps/{appId}/clusters", cluster, ClusterDTO.class, return restTemplate.post(env, "apps/{appId}/clusters", cluster, ClusterDTO.class,
cluster.getAppId()); cluster.getAppId());
} }
} }
...@@ -171,7 +174,7 @@ public class AdminServiceAPI { ...@@ -171,7 +174,7 @@ public class AdminServiceAPI {
String namespace) { String namespace) {
ReleaseDTO releaseDTO = restTemplate ReleaseDTO releaseDTO = restTemplate
.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases/latest", .get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases/latest",
ReleaseDTO.class, appId, clusterName, namespace); ReleaseDTO.class, appId, clusterName, namespace);
return releaseDTO; return releaseDTO;
} }
...@@ -194,8 +197,8 @@ public class AdminServiceAPI { ...@@ -194,8 +197,8 @@ public class AdminServiceAPI {
public void rollback(Env env, long releaseId, String operator) { public void rollback(Env env, long releaseId, String operator) {
restTemplate.put(env, restTemplate.put(env,
"releases/{releaseId}/rollback?operator={operator}", "releases/{releaseId}/rollback?operator={operator}",
null, releaseId, operator); null, releaseId, operator);
} }
} }
...@@ -205,9 +208,9 @@ public class AdminServiceAPI { ...@@ -205,9 +208,9 @@ public class AdminServiceAPI {
public List<CommitDTO> find(String appId, Env env, String clusterName, String namespaceName, int page, int size) { public List<CommitDTO> find(String appId, Env env, String clusterName, String namespaceName, int page, int size) {
CommitDTO[] commitDTOs = restTemplate.get(env, CommitDTO[] commitDTOs = restTemplate.get(env,
"apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/commit?page={page}&size={size}", "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/commit?page={page}&size={size}",
CommitDTO[].class, CommitDTO[].class,
appId, clusterName, namespaceName, page, size); appId, clusterName, namespaceName, page, size);
return Arrays.asList(commitDTOs); return Arrays.asList(commitDTOs);
} }
...@@ -218,8 +221,8 @@ public class AdminServiceAPI { ...@@ -218,8 +221,8 @@ public class AdminServiceAPI {
public NamespaceLockDTO getNamespaceLockOwner(String appId, Env env, String clusterName, String namespaceName) { public NamespaceLockDTO getNamespaceLockOwner(String appId, Env env, String clusterName, String namespaceName) {
return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/lock", return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/lock",
NamespaceLockDTO.class, NamespaceLockDTO.class,
appId, clusterName, namespaceName); appId, clusterName, namespaceName);
} }
} }
......
...@@ -73,7 +73,7 @@ public class AdminServiceAddressLocator { ...@@ -73,7 +73,7 @@ public class AdminServiceAddressLocator {
public List<ServiceDTO> getServiceList(Env env) { public List<ServiceDTO> getServiceList(Env env) {
List<ServiceDTO> services = cache.get(env); List<ServiceDTO> services = cache.get(env);
if (CollectionUtils.isEmpty(services)) { if (CollectionUtils.isEmpty(services)) {
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
List<ServiceDTO> randomConfigServices = Lists.newArrayList(services); List<ServiceDTO> randomConfigServices = Lists.newArrayList(services);
Collections.shuffle(randomConfigServices); Collections.shuffle(randomConfigServices);
...@@ -81,7 +81,7 @@ public class AdminServiceAddressLocator { ...@@ -81,7 +81,7 @@ public class AdminServiceAddressLocator {
} }
//Maintain admin server address //Maintain admin server address
class RefreshAdminServerAddressTask implements Runnable { private class RefreshAdminServerAddressTask implements Runnable {
@Override @Override
public void run() { public void run() {
......
package com.ctrip.framework.apollo.portal.api; package com.ctrip.framework.apollo.portal.api;
import com.ctrip.framework.apollo.common.exception.ServiceException;
import com.ctrip.framework.apollo.core.dto.ServiceDTO; import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.common.exception.ServiceException;
import com.ctrip.framework.apollo.portal.constant.CatEventType; import com.ctrip.framework.apollo.portal.constant.CatEventType;
import com.dianping.cat.Cat; import com.dianping.cat.Cat;
import com.dianping.cat.message.Message; import com.dianping.cat.message.Message;
...@@ -66,7 +66,7 @@ public class RetryableRestTemplate { ...@@ -66,7 +66,7 @@ public class RetryableRestTemplate {
private <T> T execute(HttpMethod method, Env env, String path, Object request, Class<T> responseType, private <T> T execute(HttpMethod method, Env env, String path, Object request, Class<T> responseType,
Object... uriVariables) { Object... uriVariables) {
if (path.startsWith("/")){ if (path.startsWith("/")) {
path = path.substring(1, path.length()); path = path.substring(1, path.length());
} }
...@@ -143,11 +143,11 @@ public class RetryableRestTemplate { ...@@ -143,11 +143,11 @@ public class RetryableRestTemplate {
Throwable nestedException = e.getCause(); Throwable nestedException = e.getCause();
if (method == HttpMethod.GET) { if (method == HttpMethod.GET) {
return nestedException instanceof SocketTimeoutException return nestedException instanceof SocketTimeoutException
|| nestedException instanceof HttpHostConnectException || nestedException instanceof HttpHostConnectException
|| nestedException instanceof ConnectTimeoutException; || nestedException instanceof ConnectTimeoutException;
} else { } else {
return nestedException instanceof HttpHostConnectException return nestedException instanceof HttpHostConnectException
|| nestedException instanceof ConnectTimeoutException; || nestedException instanceof ConnectTimeoutException;
} }
} }
......
...@@ -18,43 +18,47 @@ public class PermissionValidator { ...@@ -18,43 +18,47 @@ public class PermissionValidator {
public boolean hasModifyNamespacePermission(String appId, String namespaceName) { public boolean hasModifyNamespacePermission(String appId, String namespaceName) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.MODIFY_NAMESPACE, PermissionType.MODIFY_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName)); RoleUtils.buildNamespaceTargetId(appId, namespaceName));
} }
public boolean hasReleaseNamespacePermission(String appId, String namespaceName) { public boolean hasReleaseNamespacePermission(String appId, String namespaceName) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.RELEASE_NAMESPACE, PermissionType.RELEASE_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName)); RoleUtils.buildNamespaceTargetId(appId, namespaceName));
} }
public boolean hasAssignRolePermission(String appId) { public boolean hasAssignRolePermission(String appId) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.ASSIGN_ROLE, PermissionType.ASSIGN_ROLE,
appId); appId);
} }
public boolean hasCreateNamespacePermission(String appId) { public boolean hasCreateNamespacePermission(String appId) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.CREATE_NAMESPACE, PermissionType.CREATE_NAMESPACE,
appId); appId);
} }
public boolean hasCreateClusterPermission(String appId) { public boolean hasCreateClusterPermission(String appId) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.CREATE_CLUSTER, PermissionType.CREATE_CLUSTER,
appId); appId);
} }
public boolean hasCreateAppNamespacePermission(String appId, AppNamespace appNamespace) { public boolean hasCreateAppNamespacePermission(String appId, AppNamespace appNamespace) {
boolean isPublicAppNamespace = appNamespace.isPublic(); boolean isPublicAppNamespace = appNamespace.isPublic();
if (isPublicAppNamespace){ if (isPublicAppNamespace) {
return hasCreateNamespacePermission(appId); return hasCreateNamespacePermission(appId);
}else { } else {
return rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId()); return rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId());
} }
} }
public boolean isSuperAdmin() {
return rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId());
}
} }
...@@ -14,7 +14,6 @@ import org.springframework.http.HttpMethod; ...@@ -14,7 +14,6 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
...@@ -62,7 +61,7 @@ public class CtripUserService implements UserService { ...@@ -62,7 +61,7 @@ public class CtripUserService implements UserService {
} }
@Override @Override
public List<UserInfo> searchUsers(String keyword, int offset, int limit) { public List<UserInfo> searchUsers(String keyword, int offset, int limit) {
UserServiceRequest request = assembleSearchUserRequest(keyword, offset, limit); UserServiceRequest request = assembleSearchUserRequest(keyword, offset, limit);
HttpEntity<UserServiceRequest> entity = new HttpEntity<>(request); HttpEntity<UserServiceRequest> entity = new HttpEntity<>(request);
......
...@@ -9,7 +9,7 @@ import com.ctrip.framework.apollo.portal.entity.po.UserInfo; ...@@ -9,7 +9,7 @@ import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
public class DefaultUserInfoHolder implements UserInfoHolder { public class DefaultUserInfoHolder implements UserInfoHolder {
public DefaultUserInfoHolder(){ public DefaultUserInfoHolder() {
} }
......
...@@ -6,7 +6,6 @@ import com.ctrip.framework.apollo.portal.entity.po.UserInfo; ...@@ -6,7 +6,6 @@ import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
import com.ctrip.framework.apollo.portal.service.UserService; import com.ctrip.framework.apollo.portal.service.UserService;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
......
package com.ctrip.framework.apollo.portal.configuration; package com.ctrip.framework.apollo.portal.configuration;
import com.google.common.collect.Maps;
import com.ctrip.framework.apollo.openapi.filter.ConsumerAuthenticationFilter;
import com.ctrip.framework.apollo.openapi.util.ConsumerAuthUtil;
import com.ctrip.framework.apollo.portal.auth.LogoutHandler;
import com.ctrip.framework.apollo.portal.auth.SsoHeartbeatHandler;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.auth.ctrip.CtripLogoutHandler; import com.ctrip.framework.apollo.portal.auth.ctrip.CtripLogoutHandler;
import com.ctrip.framework.apollo.portal.auth.ctrip.CtripSsoHeartbeatHandler; import com.ctrip.framework.apollo.portal.auth.ctrip.CtripSsoHeartbeatHandler;
import com.ctrip.framework.apollo.portal.auth.ctrip.CtripUserInfoHolder; import com.ctrip.framework.apollo.portal.auth.ctrip.CtripUserInfoHolder;
...@@ -8,9 +15,6 @@ import com.ctrip.framework.apollo.portal.auth.defaultimpl.DefaultLogoutHandler; ...@@ -8,9 +15,6 @@ import com.ctrip.framework.apollo.portal.auth.defaultimpl.DefaultLogoutHandler;
import com.ctrip.framework.apollo.portal.auth.defaultimpl.DefaultSsoHeartbeatHandler; import com.ctrip.framework.apollo.portal.auth.defaultimpl.DefaultSsoHeartbeatHandler;
import com.ctrip.framework.apollo.portal.auth.defaultimpl.DefaultUserInfoHolder; import com.ctrip.framework.apollo.portal.auth.defaultimpl.DefaultUserInfoHolder;
import com.ctrip.framework.apollo.portal.auth.defaultimpl.DefaultUserService; import com.ctrip.framework.apollo.portal.auth.defaultimpl.DefaultUserService;
import com.ctrip.framework.apollo.portal.auth.LogoutHandler;
import com.ctrip.framework.apollo.portal.auth.SsoHeartbeatHandler;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.service.ServerConfigService; import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import com.ctrip.framework.apollo.portal.service.UserService; import com.ctrip.framework.apollo.portal.service.UserService;
...@@ -23,7 +27,6 @@ import org.springframework.context.annotation.Configuration; ...@@ -23,7 +27,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import java.util.EventListener; import java.util.EventListener;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.servlet.Filter; import javax.servlet.Filter;
...@@ -47,21 +50,21 @@ public class AuthConfiguration { ...@@ -47,21 +50,21 @@ public class AuthConfiguration {
private ServerConfigService serverConfigService; private ServerConfigService serverConfigService;
@Bean @Bean
public ServletListenerRegistrationBean redisAppSettingListner(){ public ServletListenerRegistrationBean redisAppSettingListner() {
ServletListenerRegistrationBean redisAppSettingListner = new ServletListenerRegistrationBean(); ServletListenerRegistrationBean redisAppSettingListner = new ServletListenerRegistrationBean();
redisAppSettingListner.setListener(listener("org.jasig.cas.client.credis.CRedisAppSettingListner")); redisAppSettingListner.setListener(listener("org.jasig.cas.client.credis.CRedisAppSettingListner"));
return redisAppSettingListner; return redisAppSettingListner;
} }
@Bean @Bean
public ServletListenerRegistrationBean singleSignOutHttpSessionListener(){ public ServletListenerRegistrationBean singleSignOutHttpSessionListener() {
ServletListenerRegistrationBean singleSignOutHttpSessionListener = new ServletListenerRegistrationBean(); ServletListenerRegistrationBean singleSignOutHttpSessionListener = new ServletListenerRegistrationBean();
singleSignOutHttpSessionListener.setListener(listener("org.jasig.cas.client.session.SingleSignOutHttpSessionListener")); singleSignOutHttpSessionListener.setListener(listener("org.jasig.cas.client.session.SingleSignOutHttpSessionListener"));
return singleSignOutHttpSessionListener; return singleSignOutHttpSessionListener;
} }
@Bean @Bean
public FilterRegistrationBean casFilter(){ public FilterRegistrationBean casFilter() {
FilterRegistrationBean singleSignOutFilter = new FilterRegistrationBean(); FilterRegistrationBean singleSignOutFilter = new FilterRegistrationBean();
singleSignOutFilter.setFilter(filter("org.jasig.cas.client.session.SingleSignOutFilter")); singleSignOutFilter.setFilter(filter("org.jasig.cas.client.session.SingleSignOutFilter"));
singleSignOutFilter.addUrlPatterns("/*"); singleSignOutFilter.addUrlPatterns("/*");
...@@ -69,15 +72,16 @@ public class AuthConfiguration { ...@@ -69,15 +72,16 @@ public class AuthConfiguration {
} }
@Bean @Bean
public FilterRegistrationBean authenticationFilter(){ public FilterRegistrationBean authenticationFilter() {
FilterRegistrationBean casFilter = new FilterRegistrationBean(); FilterRegistrationBean casFilter = new FilterRegistrationBean();
Map<String, String> filterInitParam = new HashMap(); Map<String, String> filterInitParam = Maps.newHashMap();
filterInitParam.put("redisClusterName", "casClientPrincipal"); filterInitParam.put("redisClusterName", "casClientPrincipal");
filterInitParam.put("serverName", serverConfigService.getValue("serverName")); filterInitParam.put("serverName", serverConfigService.getValue("serverName"));
filterInitParam.put("casServerLoginUrl", serverConfigService.getValue("casServerLoginUrl")); filterInitParam.put("casServerLoginUrl", serverConfigService.getValue("casServerLoginUrl"));
//we don't want to use session to store login information, since we will be deployed to a cluster, not a single instance //we don't want to use session to store login information, since we will be deployed to a cluster, not a single instance
filterInitParam.put("useSession", "false"); filterInitParam.put("useSession", "false");
filterInitParam.put("/openapi.*", "exclude");
casFilter.setInitParameters(filterInitParam); casFilter.setInitParameters(filterInitParam);
casFilter.setFilter(filter("com.ctrip.framework.apollo.sso.filter.ApolloAuthenticationFilter")); casFilter.setFilter(filter("com.ctrip.framework.apollo.sso.filter.ApolloAuthenticationFilter"));
...@@ -87,9 +91,9 @@ public class AuthConfiguration { ...@@ -87,9 +91,9 @@ public class AuthConfiguration {
} }
@Bean @Bean
public FilterRegistrationBean casValidationFilter(){ public FilterRegistrationBean casValidationFilter() {
FilterRegistrationBean casValidationFilter = new FilterRegistrationBean(); FilterRegistrationBean casValidationFilter = new FilterRegistrationBean();
Map<String, String> filterInitParam = new HashMap(); Map<String, String> filterInitParam = Maps.newHashMap();
filterInitParam.put("casServerUrlPrefix", serverConfigService.getValue("casServerUrlPrefix")); filterInitParam.put("casServerUrlPrefix", serverConfigService.getValue("casServerUrlPrefix"));
filterInitParam.put("serverName", serverConfigService.getValue("serverName")); filterInitParam.put("serverName", serverConfigService.getValue("serverName"));
filterInitParam.put("encoding", "UTF-8"); filterInitParam.put("encoding", "UTF-8");
...@@ -107,11 +111,15 @@ public class AuthConfiguration { ...@@ -107,11 +111,15 @@ public class AuthConfiguration {
} }
@Bean @Bean
public FilterRegistrationBean assertionHolder(){ public FilterRegistrationBean assertionHolder() {
FilterRegistrationBean assertionHolderFilter = new FilterRegistrationBean(); FilterRegistrationBean assertionHolderFilter = new FilterRegistrationBean();
Map<String, String> filterInitParam = Maps.newHashMap();
filterInitParam.put("/openapi.*", "exclude");
assertionHolderFilter.setInitParameters(filterInitParam);
assertionHolderFilter.setFilter(filter("com.ctrip.framework.apollo.sso.filter.ApolloAssertionThreadLocalFilter")); assertionHolderFilter.setFilter(filter("com.ctrip.framework.apollo.sso.filter.ApolloAssertionThreadLocalFilter"));
assertionHolderFilter.addUrlPatterns("/*"); assertionHolderFilter.addUrlPatterns("/*");
...@@ -119,16 +127,16 @@ public class AuthConfiguration { ...@@ -119,16 +127,16 @@ public class AuthConfiguration {
} }
@Bean @Bean
public CtripUserInfoHolder ctripUserInfoHolder(){ public CtripUserInfoHolder ctripUserInfoHolder() {
return new CtripUserInfoHolder(); return new CtripUserInfoHolder();
} }
@Bean @Bean
public CtripLogoutHandler logoutHandler(){ public CtripLogoutHandler logoutHandler() {
return new CtripLogoutHandler(); return new CtripLogoutHandler();
} }
private Filter filter(String className){ private Filter filter(String className) {
Class clazz = null; Class clazz = null;
try { try {
clazz = Class.forName(className); clazz = Class.forName(className);
...@@ -140,7 +148,7 @@ public class AuthConfiguration { ...@@ -140,7 +148,7 @@ public class AuthConfiguration {
} }
private EventListener listener(String className){ private EventListener listener(String className) {
Class clazz = null; Class clazz = null;
try { try {
clazz = Class.forName(className); clazz = Class.forName(className);
...@@ -168,6 +176,16 @@ public class AuthConfiguration { ...@@ -168,6 +176,16 @@ public class AuthConfiguration {
@Configuration @Configuration
static class DefaultAuthAutoConfiguration { static class DefaultAuthAutoConfiguration {
@Bean
public FilterRegistrationBean openApiAuthenticationFilter(ConsumerAuthUtil consumerAuthUtil) {
FilterRegistrationBean openApiFilter = new FilterRegistrationBean();
openApiFilter.setFilter(new ConsumerAuthenticationFilter(consumerAuthUtil));
openApiFilter.addUrlPatterns("/openapi/*");
return openApiFilter;
}
@Bean @Bean
@ConditionalOnMissingBean(SsoHeartbeatHandler.class) @ConditionalOnMissingBean(SsoHeartbeatHandler.class)
public SsoHeartbeatHandler defaultSsoHeartbeatHandler() { public SsoHeartbeatHandler defaultSsoHeartbeatHandler() {
...@@ -176,13 +194,13 @@ public class AuthConfiguration { ...@@ -176,13 +194,13 @@ public class AuthConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(UserInfoHolder.class) @ConditionalOnMissingBean(UserInfoHolder.class)
public DefaultUserInfoHolder notCtripUserInfoHolder(){ public DefaultUserInfoHolder notCtripUserInfoHolder() {
return new DefaultUserInfoHolder(); return new DefaultUserInfoHolder();
} }
@Bean @Bean
@ConditionalOnMissingBean(LogoutHandler.class) @ConditionalOnMissingBean(LogoutHandler.class)
public DefaultLogoutHandler logoutHandler(){ public DefaultLogoutHandler logoutHandler() {
return new DefaultLogoutHandler(); return new DefaultLogoutHandler();
} }
......
...@@ -36,11 +36,11 @@ public class WebContextConfiguration { ...@@ -36,11 +36,11 @@ public class WebContextConfiguration {
String loggingServerPort = serverConfigService.getValue("loggingServerPort"); String loggingServerPort = serverConfigService.getValue("loggingServerPort");
String credisServiceUrl = serverConfigService.getValue("credisServiceUrl"); String credisServiceUrl = serverConfigService.getValue("credisServiceUrl");
servletContext.setInitParameter("loggingServerIP", servletContext.setInitParameter("loggingServerIP",
Strings.isNullOrEmpty(loggingServerIP) ? "" : loggingServerIP); Strings.isNullOrEmpty(loggingServerIP) ? "" : loggingServerIP);
servletContext.setInitParameter("loggingServerPort", servletContext.setInitParameter("loggingServerPort",
Strings.isNullOrEmpty(loggingServerPort) ? "" : loggingServerPort); Strings.isNullOrEmpty(loggingServerPort) ? "" : loggingServerPort);
servletContext.setInitParameter("credisServiceUrl", servletContext.setInitParameter("credisServiceUrl",
Strings.isNullOrEmpty(credisServiceUrl) ? "" : credisServiceUrl); Strings.isNullOrEmpty(credisServiceUrl) ? "" : credisServiceUrl);
} }
}; };
} }
......
...@@ -2,7 +2,9 @@ package com.ctrip.framework.apollo.portal.constant; ...@@ -2,7 +2,9 @@ package com.ctrip.framework.apollo.portal.constant;
public interface PermissionType { public interface PermissionType {
/** APP level permission */ /**
* APP level permission
*/
String CREATE_NAMESPACE = "CreateNamespace"; String CREATE_NAMESPACE = "CreateNamespace";
...@@ -13,7 +15,9 @@ public interface PermissionType { ...@@ -13,7 +15,9 @@ public interface PermissionType {
*/ */
String ASSIGN_ROLE = "AssignRole"; String ASSIGN_ROLE = "AssignRole";
/** namespace level permission*/ /**
* namespace level permission
*/
String MODIFY_NAMESPACE = "ModifyNamespace"; String MODIFY_NAMESPACE = "ModifyNamespace";
......
...@@ -2,11 +2,12 @@ package com.ctrip.framework.apollo.portal.controller; ...@@ -2,11 +2,12 @@ package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.http.MultiResponseEntity; import com.ctrip.framework.apollo.common.http.MultiResponseEntity;
import com.ctrip.framework.apollo.common.http.RichResponseEntity; import com.ctrip.framework.apollo.common.http.RichResponseEntity;
import com.ctrip.framework.apollo.common.utils.InputValidator; import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.portal.PortalSettings; import com.ctrip.framework.apollo.portal.PortalSettings;
import com.ctrip.framework.apollo.portal.entity.po.UserInfo; import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
import com.ctrip.framework.apollo.portal.entity.vo.EnvClusterInfo; import com.ctrip.framework.apollo.portal.entity.vo.EnvClusterInfo;
...@@ -27,7 +28,6 @@ import org.springframework.web.client.HttpClientErrorException; ...@@ -27,7 +28,6 @@ import org.springframework.web.client.HttpClientErrorException;
import java.util.List; import java.util.List;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkArgument;
@RestController @RestController
@RequestMapping("/apps") @RequestMapping("/apps")
...@@ -75,14 +75,14 @@ public class AppController { ...@@ -75,14 +75,14 @@ public class AppController {
@RequestMapping(value = "", method = RequestMethod.POST) @RequestMapping(value = "", method = RequestMethod.POST)
public ResponseEntity<Void> create(@RequestBody App app) { public ResponseEntity<Void> create(@RequestBody App app) {
checkArgument(app.getName(), app.getAppId(), app.getOwnerName(), RequestPrecondition.checkArgumentsNotEmpty(app.getName(), app.getAppId(), app.getOwnerName(),
app.getOrgId(), app.getOrgName()); app.getOrgId(), app.getOrgName());
if (!InputValidator.isValidClusterNamespace(app.getAppId())) { if (!InputValidator.isValidClusterNamespace(app.getAppId())) {
throw new BadRequestException(String.format("AppId格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE)); throw new BadRequestException(String.format("AppId格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE));
} }
UserInfo userInfo = userService.findByUserId(app.getOwnerName()); UserInfo userInfo = userService.findByUserId(app.getOwnerName());
if (userInfo == null){ if (userInfo == null) {
throw new BadRequestException("应用负责人不存在"); throw new BadRequestException("应用负责人不存在");
} }
app.setOwnerEmail(userInfo.getEmail()); app.setOwnerEmail(userInfo.getEmail());
...@@ -98,7 +98,7 @@ public class AppController { ...@@ -98,7 +98,7 @@ public class AppController {
"application/json"}) "application/json"})
public ResponseEntity<Void> create(@PathVariable String env, @RequestBody App app) { public ResponseEntity<Void> create(@PathVariable String env, @RequestBody App app) {
checkArgument(app.getName(), app.getAppId(), app.getOwnerEmail(), app.getOwnerName(), RequestPrecondition.checkArgumentsNotEmpty(app.getName(), app.getAppId(), app.getOwnerEmail(), app.getOwnerName(),
app.getOrgId(), app.getOrgName()); app.getOrgId(), app.getOrgName());
if (!InputValidator.isValidClusterNamespace(app.getAppId())) { if (!InputValidator.isValidClusterNamespace(app.getAppId())) {
throw new BadRequestException(InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE); throw new BadRequestException(InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE);
......
package com.ctrip.framework.apollo.portal.controller; package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.common.dto.ClusterDTO; import com.ctrip.framework.apollo.common.dto.ClusterDTO;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.service.ClusterService; import com.ctrip.framework.apollo.portal.service.ClusterService;
...@@ -15,7 +16,6 @@ import org.springframework.web.bind.annotation.RequestMapping; ...@@ -15,7 +16,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkArgument;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkModel; import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkModel;
@RestController @RestController
...@@ -29,10 +29,10 @@ public class ClusterController { ...@@ -29,10 +29,10 @@ public class ClusterController {
@PreAuthorize(value = "@permissionValidator.hasCreateClusterPermission(#appId)") @PreAuthorize(value = "@permissionValidator.hasCreateClusterPermission(#appId)")
@RequestMapping(value = "apps/{appId}/envs/{env}/clusters", method = RequestMethod.POST) @RequestMapping(value = "apps/{appId}/envs/{env}/clusters", method = RequestMethod.POST)
public ClusterDTO createCluster(@PathVariable String appId, @PathVariable String env, public ClusterDTO createCluster(@PathVariable String appId, @PathVariable String env,
@RequestBody ClusterDTO cluster){ @RequestBody ClusterDTO cluster) {
checkModel(cluster != null); checkModel(cluster != null);
checkArgument(cluster.getAppId(), cluster.getName()); RequestPrecondition.checkArgumentsNotEmpty(cluster.getAppId(), cluster.getName());
if (!InputValidator.isValidClusterNamespace(cluster.getName())) { if (!InputValidator.isValidClusterNamespace(cluster.getName())) {
throw new BadRequestException(String.format("Cluster格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE)); throw new BadRequestException(String.format("Cluster格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE));
......
package com.ctrip.framework.apollo.portal.controller; package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.common.dto.CommitDTO; import com.ctrip.framework.apollo.common.dto.CommitDTO;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.service.CommitService; import com.ctrip.framework.apollo.portal.service.CommitService;
...@@ -23,7 +23,7 @@ public class CommitController { ...@@ -23,7 +23,7 @@ public class CommitController {
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/commits") @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/commits")
public List<CommitDTO> find(@PathVariable String appId, @PathVariable String env, public List<CommitDTO> find(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size){ @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) {
RequestPrecondition.checkNumberPositive(size); RequestPrecondition.checkNumberPositive(size);
RequestPrecondition.checkNumberNotNegative(page); RequestPrecondition.checkNumberNotNegative(page);
......
package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
import com.ctrip.framework.apollo.openapi.service.ConsumerService;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
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.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RestController
@RequestMapping("/consumers")
public class ConsumerController {
private static final Date DEFAULT_EXPIRES = new GregorianCalendar(2099, Calendar.JANUARY, 1)
.getTime();
@Autowired
private ConsumerService consumerService;
@Autowired
private UserInfoHolder userInfoHolder;
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@RequestMapping(value = "/{consumerId}/tokens", method = RequestMethod.POST)
public ConsumerToken createConsumerToken(@PathVariable long consumerId,
@RequestParam(value = "expires", required = false)
@DateTimeFormat(pattern = "yyyyMMddHHmmss") Date
expires) {
if (expires == null) {
expires = DEFAULT_EXPIRES;
}
ConsumerToken consumerToken = generateConsumerToken(consumerId, expires);
return consumerService.createConsumerToken(consumerToken);
}
private ConsumerToken generateConsumerToken(long consumerId, Date expires) {
String createdBy = userInfoHolder.getUser().getUserId();
Date createdTime = new Date();
ConsumerToken consumerToken = new ConsumerToken();
consumerToken.setConsumerId(consumerId);
consumerToken.setExpires(expires);
consumerToken.setDataChangeCreatedBy(createdBy);
consumerToken.setDataChangeCreatedTime(createdTime);
consumerToken.setDataChangeLastModifiedBy(createdBy);
consumerToken.setDataChangeLastModifiedTime(createdTime);
consumerService.generateAndEnrichConsumerToken(consumerToken);
return consumerToken;
}
}
...@@ -18,7 +18,7 @@ public class EnvController { ...@@ -18,7 +18,7 @@ public class EnvController {
private PortalSettings portalSettings; private PortalSettings portalSettings;
@RequestMapping(value = "", method = RequestMethod.GET) @RequestMapping(value = "", method = RequestMethod.GET)
public List<Env> envs(){ public List<Env> envs() {
return portalSettings.getActiveEnvs(); return portalSettings.getActiveEnvs();
} }
......
package com.ctrip.framework.apollo.portal.controller; package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.entity.vo.ItemDiffs; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.entity.form.NamespaceSyncModel; import com.ctrip.framework.apollo.portal.entity.form.NamespaceSyncModel;
import com.ctrip.framework.apollo.portal.entity.form.NamespaceTextModel; import com.ctrip.framework.apollo.portal.entity.form.NamespaceTextModel;
import com.ctrip.framework.apollo.portal.service.ConfigService; import com.ctrip.framework.apollo.portal.entity.vo.ItemDiffs;
import com.ctrip.framework.apollo.portal.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
...@@ -29,14 +30,16 @@ import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkM ...@@ -29,14 +30,16 @@ import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkM
public class ItemController { public class ItemController {
@Autowired @Autowired
private ConfigService configService; private ItemService configService;
@Autowired
private UserInfoHolder userInfoHolder;
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)") @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = { @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = {
"application/json"}) "application/json"})
public void modifyItemsByText(@PathVariable String appId, @PathVariable String env, public void modifyItemsByText(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
@RequestBody NamespaceTextModel model) { @RequestBody NamespaceTextModel model) {
checkModel(model != null); checkModel(model != null);
...@@ -52,7 +55,7 @@ public class ItemController { ...@@ -52,7 +55,7 @@ public class ItemController {
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.POST) @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.POST)
public ItemDTO createItem(@PathVariable String appId, @PathVariable String env, public ItemDTO createItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
@RequestBody ItemDTO item){ @RequestBody ItemDTO item) {
checkModel(isValidItem(item)); checkModel(isValidItem(item));
return configService.createItem(appId, Env.valueOf(env), clusterName, namespaceName, item); return configService.createItem(appId, Env.valueOf(env), clusterName, namespaceName, item);
...@@ -61,8 +64,8 @@ public class ItemController { ...@@ -61,8 +64,8 @@ public class ItemController {
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)") @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.PUT) @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.PUT)
public void updateItem(@PathVariable String appId, @PathVariable String env, public void updateItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
@RequestBody ItemDTO item){ @RequestBody ItemDTO item) {
checkModel(isValidItem(item)); checkModel(isValidItem(item));
configService.updateItem(appId, Env.valueOf(env), clusterName, namespaceName, item); configService.updateItem(appId, Env.valueOf(env), clusterName, namespaceName, item);
...@@ -73,27 +76,26 @@ public class ItemController { ...@@ -73,27 +76,26 @@ public class ItemController {
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}", method = RequestMethod.DELETE) @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}", method = RequestMethod.DELETE)
public void deleteItem(@PathVariable String appId, @PathVariable String env, public void deleteItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
@PathVariable long itemId){ @PathVariable long itemId) {
if (itemId <= 0){ if (itemId <= 0) {
throw new BadRequestException("item id invalid"); throw new BadRequestException("item id invalid");
} }
configService.deleteItem(Env.valueOf(env), itemId); configService.deleteItem(Env.valueOf(env), itemId, userInfoHolder.getUser().getUserId());
} }
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items") @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items")
public List<ItemDTO> findItems(@PathVariable String appId, @PathVariable String env, public List<ItemDTO> findItems(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
@RequestParam(defaultValue = "lineNum") String orderBy){ @RequestParam(defaultValue = "lineNum") String orderBy) {
List<ItemDTO> items = configService.findItems(appId, Env.valueOf(env), clusterName, namespaceName); List<ItemDTO> items = configService.findItems(appId, Env.valueOf(env), clusterName, namespaceName);
if ("lastModifiedTime".equals(orderBy)){ if ("lastModifiedTime".equals(orderBy)) {
Collections.sort(items, (o1, o2) -> { Collections.sort(items, (o1, o2) -> {
if (o1.getDataChangeLastModifiedTime().after(o2.getDataChangeLastModifiedTime())){ if (o1.getDataChangeLastModifiedTime().after(o2.getDataChangeLastModifiedTime())) {
return -1; return -1;
} }
if (o1.getDataChangeLastModifiedTime().before(o2.getDataChangeLastModifiedTime())){ if (o1.getDataChangeLastModifiedTime().before(o2.getDataChangeLastModifiedTime())) {
return 1; return 1;
} }
return 0; return 0;
...@@ -104,7 +106,7 @@ public class ItemController { ...@@ -104,7 +106,7 @@ public class ItemController {
@RequestMapping(value = "/namespaces/{namespaceName}/diff", method = RequestMethod.POST, consumes = { @RequestMapping(value = "/namespaces/{namespaceName}/diff", method = RequestMethod.POST, consumes = {
"application/json"}) "application/json"})
public List<ItemDiffs> diff(@RequestBody NamespaceSyncModel model){ public List<ItemDiffs> diff(@RequestBody NamespaceSyncModel model) {
checkModel(model != null && !model.isInvalid()); checkModel(model != null && !model.isInvalid());
return configService.compare(model.getSyncToNamespaces(), model.getSyncItems()); return configService.compare(model.getSyncToNamespaces(), model.getSyncItems());
...@@ -114,14 +116,14 @@ public class ItemController { ...@@ -114,14 +116,14 @@ public class ItemController {
@RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = { @RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = {
"application/json"}) "application/json"})
public ResponseEntity<Void> update(@PathVariable String appId, @PathVariable String namespaceName, public ResponseEntity<Void> update(@PathVariable String appId, @PathVariable String namespaceName,
@RequestBody NamespaceSyncModel model){ @RequestBody NamespaceSyncModel model) {
checkModel(model != null && !model.isInvalid()); checkModel(model != null && !model.isInvalid());
configService.syncItems(model.getSyncToNamespaces(), model.getSyncItems()); configService.syncItems(model.getSyncToNamespaces(), model.getSyncItems());
return ResponseEntity.status(HttpStatus.OK).build(); return ResponseEntity.status(HttpStatus.OK).build();
} }
private boolean isValidItem(ItemDTO item){ private boolean isValidItem(ItemDTO item) {
return item != null && !StringUtils.isContainEmpty(item.getKey()); return item != null && !StringUtils.isContainEmpty(item.getKey());
} }
......
package com.ctrip.framework.apollo.portal.controller; package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.common.entity.AppNamespace; import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.utils.InputValidator; import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.entity.form.NamespaceCreationModel; import com.ctrip.framework.apollo.portal.entity.form.NamespaceCreationModel;
...@@ -33,7 +34,6 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -33,7 +34,6 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkArgument;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkModel; import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkModel;
@RestController @RestController
...@@ -71,7 +71,8 @@ public class NamespaceController { ...@@ -71,7 +71,8 @@ public class NamespaceController {
for (NamespaceCreationModel model : models) { for (NamespaceCreationModel model : models) {
NamespaceDTO namespace = model.getNamespace(); NamespaceDTO namespace = model.getNamespace();
checkArgument(model.getEnv(), namespace.getAppId(), namespace.getClusterName(), namespace.getNamespaceName()); RequestPrecondition
.checkArgumentsNotEmpty(model.getEnv(), namespace.getAppId(), namespace.getClusterName(), namespace.getNamespaceName());
try { try {
// TODO: 16/6/17 某些环境创建失败,统一处理这种场景 // TODO: 16/6/17 某些环境创建失败,统一处理这种场景
...@@ -89,11 +90,11 @@ public class NamespaceController { ...@@ -89,11 +90,11 @@ public class NamespaceController {
@RequestMapping(value = "/apps/{appId}/appnamespaces", method = RequestMethod.POST) @RequestMapping(value = "/apps/{appId}/appnamespaces", method = RequestMethod.POST)
public AppNamespace createAppNamespace(@PathVariable String appId, @RequestBody AppNamespace appNamespace) { public AppNamespace createAppNamespace(@PathVariable String appId, @RequestBody AppNamespace appNamespace) {
checkArgument(appNamespace.getAppId(), appNamespace.getName()); RequestPrecondition.checkArgumentsNotEmpty(appNamespace.getAppId(), appNamespace.getName());
if (!InputValidator.isValidAppNamespace(appNamespace.getName())) { if (!InputValidator.isValidAppNamespace(appNamespace.getName())) {
throw new BadRequestException(String.format("Namespace格式错误: %s", throw new BadRequestException(String.format("Namespace格式错误: %s",
InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE + " & " InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE + " & "
+ InputValidator.INVALID_NAMESPACE_NAMESPACE_MESSAGE)); + InputValidator.INVALID_NAMESPACE_NAMESPACE_MESSAGE));
} }
//add app org id as prefix //add app org id as prefix
......
...@@ -17,9 +17,9 @@ public class NamespaceLockController { ...@@ -17,9 +17,9 @@ public class NamespaceLockController {
@RequestMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/lock") @RequestMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/lock")
public NamespaceLockDTO getNamespaceLock(@PathVariable String appId, @PathVariable String env, public NamespaceLockDTO getNamespaceLock(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName){ @PathVariable String clusterName, @PathVariable String namespaceName) {
return namespaceLockService.getNamespaceLock(appId, Env.valueOf(env), clusterName, namespaceName); return namespaceLockService.getNamespaceLock(appId, Env.valueOf(env), clusterName, namespaceName);
} }
} }
...@@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.portal.controller; ...@@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.portal.controller;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.constant.RoleType; import com.ctrip.framework.apollo.portal.constant.RoleType;
import com.ctrip.framework.apollo.portal.entity.po.UserInfo; import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
...@@ -26,8 +27,6 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -26,8 +27,6 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.Set; import java.util.Set;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkArgument;
@RestController @RestController
public class PermissionController { public class PermissionController {
...@@ -56,13 +55,13 @@ public class PermissionController { ...@@ -56,13 +55,13 @@ public class PermissionController {
permissionCondition.setHasPermission( permissionCondition.setHasPermission(
rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), permissionType, rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), permissionType,
RoleUtils.buildNamespaceTargetId(appId, namespaceName))); RoleUtils.buildNamespaceTargetId(appId, namespaceName)));
return ResponseEntity.ok().body(permissionCondition); return ResponseEntity.ok().body(permissionCondition);
} }
@RequestMapping("/permissions/root") @RequestMapping("/permissions/root")
public ResponseEntity<PermissionCondition> hasRootPermission(){ public ResponseEntity<PermissionCondition> hasRootPermission() {
PermissionCondition permissionCondition = new PermissionCondition(); PermissionCondition permissionCondition = new PermissionCondition();
permissionCondition.setHasPermission(rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId())); permissionCondition.setHasPermission(rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId()));
...@@ -72,7 +71,7 @@ public class PermissionController { ...@@ -72,7 +71,7 @@ public class PermissionController {
@RequestMapping("/apps/{appId}/namespaces/{namespaceName}/role_users") @RequestMapping("/apps/{appId}/namespaces/{namespaceName}/role_users")
public NamespaceRolesAssignedUsers getNamespaceRoles(@PathVariable String appId, @PathVariable String namespaceName){ public NamespaceRolesAssignedUsers getNamespaceRoles(@PathVariable String appId, @PathVariable String namespaceName) {
NamespaceRolesAssignedUsers assignedUsers = new NamespaceRolesAssignedUsers(); NamespaceRolesAssignedUsers assignedUsers = new NamespaceRolesAssignedUsers();
assignedUsers.setNamespaceName(namespaceName); assignedUsers.setNamespaceName(namespaceName);
...@@ -92,16 +91,16 @@ public class PermissionController { ...@@ -92,16 +91,16 @@ public class PermissionController {
@PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)")
@RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/roles/{roleType}", method = RequestMethod.POST) @RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/roles/{roleType}", method = RequestMethod.POST)
public ResponseEntity<Void> assignNamespaceRoleToUser(@PathVariable String appId, @PathVariable String namespaceName, public ResponseEntity<Void> assignNamespaceRoleToUser(@PathVariable String appId, @PathVariable String namespaceName,
@PathVariable String roleType, @RequestBody String user){ @PathVariable String roleType, @RequestBody String user) {
checkUserExists(user); checkUserExists(user);
checkArgument(user); RequestPrecondition.checkArgumentsNotEmpty(user);
if (!RoleType.isValidRoleType(roleType)){ if (!RoleType.isValidRoleType(roleType)) {
throw new BadRequestException("role type is illegal"); throw new BadRequestException("role type is illegal");
} }
Set<String> assignedUser = rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType), Set<String> assignedUser = rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType),
Sets.newHashSet(user), userInfoHolder.getUser().getUserId()); Sets.newHashSet(user), userInfoHolder.getUser().getUserId());
if (CollectionUtils.isEmpty(assignedUser)){ if (CollectionUtils.isEmpty(assignedUser)) {
throw new BadRequestException(user + "已授权"); throw new BadRequestException(user + "已授权");
} }
...@@ -111,19 +110,19 @@ public class PermissionController { ...@@ -111,19 +110,19 @@ public class PermissionController {
@PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)")
@RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/roles/{roleType}", method = RequestMethod.DELETE) @RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/roles/{roleType}", method = RequestMethod.DELETE)
public ResponseEntity<Void> removeNamespaceRoleFromUser(@PathVariable String appId, @PathVariable String namespaceName, public ResponseEntity<Void> removeNamespaceRoleFromUser(@PathVariable String appId, @PathVariable String namespaceName,
@PathVariable String roleType, @RequestParam String user){ @PathVariable String roleType, @RequestParam String user) {
checkArgument(user); RequestPrecondition.checkArgumentsNotEmpty(user);
if (!RoleType.isValidRoleType(roleType)){ if (!RoleType.isValidRoleType(roleType)) {
throw new BadRequestException("role type is illegal"); throw new BadRequestException("role type is illegal");
} }
rolePermissionService.removeRoleFromUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType), rolePermissionService.removeRoleFromUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType),
Sets.newHashSet(user), userInfoHolder.getUser().getUserId()); Sets.newHashSet(user), userInfoHolder.getUser().getUserId());
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@RequestMapping(value = "/apps/{appId}/role_users") @RequestMapping(value = "/apps/{appId}/role_users")
public AppRolesAssignedUsers getAppRoles(@PathVariable String appId){ public AppRolesAssignedUsers getAppRoles(@PathVariable String appId) {
AppRolesAssignedUsers users = new AppRolesAssignedUsers(); AppRolesAssignedUsers users = new AppRolesAssignedUsers();
users.setAppId(appId); users.setAppId(appId);
...@@ -136,16 +135,16 @@ public class PermissionController { ...@@ -136,16 +135,16 @@ public class PermissionController {
@PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)")
@RequestMapping(value = "/apps/{appId}/roles/{roleType}", method = RequestMethod.POST) @RequestMapping(value = "/apps/{appId}/roles/{roleType}", method = RequestMethod.POST)
public ResponseEntity<Void> assignAppRoleToUser(@PathVariable String appId, @PathVariable String roleType, public ResponseEntity<Void> assignAppRoleToUser(@PathVariable String appId, @PathVariable String roleType,
@RequestBody String user){ @RequestBody String user) {
checkUserExists(user); checkUserExists(user);
checkArgument(user); RequestPrecondition.checkArgumentsNotEmpty(user);
if (!RoleType.isValidRoleType(roleType)){ if (!RoleType.isValidRoleType(roleType)) {
throw new BadRequestException("role type is illegal"); throw new BadRequestException("role type is illegal");
} }
Set<String> assignedUsers = rolePermissionService.assignRoleToUsers(RoleUtils.buildAppRoleName(appId, roleType), Set<String> assignedUsers = rolePermissionService.assignRoleToUsers(RoleUtils.buildAppRoleName(appId, roleType),
Sets.newHashSet(user), userInfoHolder.getUser().getUserId()); Sets.newHashSet(user), userInfoHolder.getUser().getUserId());
if (CollectionUtils.isEmpty(assignedUsers)){ if (CollectionUtils.isEmpty(assignedUsers)) {
throw new BadRequestException(user + "已授权"); throw new BadRequestException(user + "已授权");
} }
...@@ -155,14 +154,14 @@ public class PermissionController { ...@@ -155,14 +154,14 @@ public class PermissionController {
@PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)")
@RequestMapping(value = "/apps/{appId}/roles/{roleType}", method = RequestMethod.DELETE) @RequestMapping(value = "/apps/{appId}/roles/{roleType}", method = RequestMethod.DELETE)
public ResponseEntity<Void> removeAppRoleFromUser(@PathVariable String appId, @PathVariable String roleType, public ResponseEntity<Void> removeAppRoleFromUser(@PathVariable String appId, @PathVariable String roleType,
@RequestParam String user){ @RequestParam String user) {
checkArgument(user); RequestPrecondition.checkArgumentsNotEmpty(user);
if (!RoleType.isValidRoleType(roleType)){ if (!RoleType.isValidRoleType(roleType)) {
throw new BadRequestException("role type is illegal"); throw new BadRequestException("role type is illegal");
} }
rolePermissionService.removeRoleFromUsers(RoleUtils.buildAppRoleName(appId, roleType), rolePermissionService.removeRoleFromUsers(RoleUtils.buildAppRoleName(appId, roleType),
Sets.newHashSet(user), userInfoHolder.getUser().getUserId()); Sets.newHashSet(user), userInfoHolder.getUser().getUserId());
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
......
package com.ctrip.framework.apollo.portal.controller; package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.common.dto.ReleaseDTO; import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.entity.form.NamespaceReleaseModel; import com.ctrip.framework.apollo.portal.entity.form.NamespaceReleaseModel;
import com.ctrip.framework.apollo.portal.entity.vo.ReleaseCompareResult; import com.ctrip.framework.apollo.portal.entity.vo.ReleaseCompareResult;
...@@ -28,7 +28,7 @@ public class ReleaseController { ...@@ -28,7 +28,7 @@ public class ReleaseController {
private ReleaseService releaseService; private ReleaseService releaseService;
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName)") @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/release") @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/release", method = RequestMethod.POST)
public ReleaseDTO createRelease(@PathVariable String appId, public ReleaseDTO createRelease(@PathVariable String appId,
@PathVariable String env, @PathVariable String clusterName, @PathVariable String env, @PathVariable String clusterName,
@PathVariable String namespaceName, @RequestBody NamespaceReleaseModel model) { @PathVariable String namespaceName, @RequestBody NamespaceReleaseModel model) {
......
...@@ -2,17 +2,18 @@ package com.ctrip.framework.apollo.portal.controller; ...@@ -2,17 +2,18 @@ package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.utils.BeanUtils; import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.entity.po.ServerConfig; import com.ctrip.framework.apollo.portal.entity.po.ServerConfig;
import com.ctrip.framework.apollo.portal.repository.ServerConfigRepository; import com.ctrip.framework.apollo.portal.repository.ServerConfigRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody; 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.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkArgument;
import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkModel; import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkModel;
/** /**
...@@ -26,11 +27,12 @@ public class ServerConfigController { ...@@ -26,11 +27,12 @@ public class ServerConfigController {
@Autowired @Autowired
private UserInfoHolder userInfoHolder; private UserInfoHolder userInfoHolder;
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@RequestMapping(value = "/server/config", method = RequestMethod.POST) @RequestMapping(value = "/server/config", method = RequestMethod.POST)
public ServerConfig createOrUpdate(@RequestBody ServerConfig serverConfig) { public ServerConfig createOrUpdate(@RequestBody ServerConfig serverConfig) {
checkModel(serverConfig != null); checkModel(serverConfig != null);
checkArgument(serverConfig.getKey(), serverConfig.getValue()); RequestPrecondition.checkArgumentsNotEmpty(serverConfig.getKey(), serverConfig.getValue());
String modifiedBy = userInfoHolder.getUser().getUserId(); String modifiedBy = userInfoHolder.getUser().getUserId();
......
...@@ -30,7 +30,7 @@ public class UserInfoController { ...@@ -30,7 +30,7 @@ public class UserInfoController {
@RequestMapping("/user") @RequestMapping("/user")
public UserInfo getCurrentUserName() { public UserInfo getCurrentUserName() {
return userInfoHolder.getUser(); return userInfoHolder.getUser();
} }
@RequestMapping("/user/logout") @RequestMapping("/user/logout")
......
...@@ -9,7 +9,7 @@ import org.springframework.stereotype.Component; ...@@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
@Component @Component
@Profile("ctrip") @Profile("ctrip")
public class BizLoggingCustomizer extends LoggingCustomizer{ public class BizLoggingCustomizer extends LoggingCustomizer {
private static final String CLOGGING_SERVER_URL_KEY = "clogging.server.url"; private static final String CLOGGING_SERVER_URL_KEY = "clogging.server.url";
private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port"; private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port";
...@@ -22,7 +22,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{ ...@@ -22,7 +22,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{
@Override @Override
protected String cloggingUrl() { protected String cloggingUrl() {
if (cloggingUrl == null){ if (cloggingUrl == null) {
cloggingUrl = serverConfigService.getValue(CLOGGING_SERVER_URL_KEY); cloggingUrl = serverConfigService.getValue(CLOGGING_SERVER_URL_KEY);
} }
return cloggingUrl; return cloggingUrl;
...@@ -30,7 +30,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{ ...@@ -30,7 +30,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{
@Override @Override
protected String cloggingPort() { protected String cloggingPort() {
if (cloggingPort == null){ if (cloggingPort == null) {
cloggingPort = serverConfigService.getValue(CLOGGING_SERVER_PORT_KEY); cloggingPort = serverConfigService.getValue(CLOGGING_SERVER_PORT_KEY);
} }
return cloggingPort; return cloggingPort;
......
...@@ -12,6 +12,7 @@ public class NamespaceReleaseModel implements Verifiable { ...@@ -12,6 +12,7 @@ public class NamespaceReleaseModel implements Verifiable {
private String namespaceName; private String namespaceName;
private String releaseTitle; private String releaseTitle;
private String releaseComment; private String releaseComment;
private String releasedBy;
@Override @Override
public boolean isInvalid() { public boolean isInvalid() {
...@@ -66,4 +67,11 @@ public class NamespaceReleaseModel implements Verifiable { ...@@ -66,4 +67,11 @@ public class NamespaceReleaseModel implements Verifiable {
this.releaseComment = releaseComment; this.releaseComment = releaseComment;
} }
public String getReleasedBy() {
return releasedBy;
}
public void setReleasedBy(String releasedBy) {
this.releasedBy = releasedBy;
}
} }
package com.ctrip.framework.apollo.portal.entity.form; package com.ctrip.framework.apollo.portal.entity.form;
import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceIdentifer; import com.ctrip.framework.apollo.portal.entity.vo.NamespaceIdentifier;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
...@@ -9,27 +9,27 @@ import java.util.List; ...@@ -9,27 +9,27 @@ import java.util.List;
public class NamespaceSyncModel implements Verifiable { public class NamespaceSyncModel implements Verifiable {
private List<NamespaceIdentifer> syncToNamespaces; private List<NamespaceIdentifier> syncToNamespaces;
private List<ItemDTO> syncItems; private List<ItemDTO> syncItems;
@Override @Override
public boolean isInvalid() { public boolean isInvalid() {
if (CollectionUtils.isEmpty(syncToNamespaces) || CollectionUtils.isEmpty(syncItems)){ if (CollectionUtils.isEmpty(syncToNamespaces) || CollectionUtils.isEmpty(syncItems)) {
return true; return true;
} }
for (NamespaceIdentifer namespaceIdentifer: syncToNamespaces){ for (NamespaceIdentifier namespaceIdentifier : syncToNamespaces) {
if (namespaceIdentifer.isInvalid()){ if (namespaceIdentifier.isInvalid()) {
return true; return true;
} }
} }
return false; return false;
} }
public List<NamespaceIdentifer> getSyncToNamespaces() { public List<NamespaceIdentifier> getSyncToNamespaces() {
return syncToNamespaces; return syncToNamespaces;
} }
public void setSyncToNamespaces(List<NamespaceIdentifer> syncToNamespaces) { public void setSyncToNamespaces(List<NamespaceIdentifier> syncToNamespaces) {
this.syncToNamespaces = syncToNamespaces; this.syncToNamespaces = syncToNamespaces;
} }
......
...@@ -17,9 +17,10 @@ public class NamespaceTextModel implements Verifiable { ...@@ -17,9 +17,10 @@ public class NamespaceTextModel implements Verifiable {
@Override @Override
public boolean isInvalid(){ public boolean isInvalid() {
return StringUtils.isContainEmpty(appId, env, clusterName, namespaceName) || namespaceId <= 0; return StringUtils.isContainEmpty(appId, env, clusterName, namespaceName) || namespaceId <= 0;
} }
public String getAppId() { public String getAppId() {
return appId; return appId;
} }
......
...@@ -9,7 +9,7 @@ public class EnvClusterInfo { ...@@ -9,7 +9,7 @@ public class EnvClusterInfo {
private Env env; private Env env;
private List<ClusterDTO> clusters; private List<ClusterDTO> clusters;
public EnvClusterInfo(Env env){ public EnvClusterInfo(Env env) {
this.env = env; this.env = env;
} }
......
...@@ -3,18 +3,19 @@ package com.ctrip.framework.apollo.portal.entity.vo; ...@@ -3,18 +3,19 @@ package com.ctrip.framework.apollo.portal.entity.vo;
import com.ctrip.framework.apollo.common.dto.ItemChangeSets; import com.ctrip.framework.apollo.common.dto.ItemChangeSets;
public class ItemDiffs { public class ItemDiffs {
private NamespaceIdentifer namespace; private NamespaceIdentifier namespace;
private ItemChangeSets diffs; private ItemChangeSets diffs;
private String extInfo; private String extInfo;
public ItemDiffs(NamespaceIdentifer namespace){ public ItemDiffs(NamespaceIdentifier namespace) {
this.namespace = namespace; this.namespace = namespace;
} }
public NamespaceIdentifer getNamespace() {
public NamespaceIdentifier getNamespace() {
return namespace; return namespace;
} }
public void setNamespace(NamespaceIdentifer namespace) { public void setNamespace(NamespaceIdentifier namespace) {
this.namespace = namespace; this.namespace = namespace;
} }
......
...@@ -4,7 +4,7 @@ import com.ctrip.framework.apollo.core.enums.Env; ...@@ -4,7 +4,7 @@ import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.entity.form.Verifiable; import com.ctrip.framework.apollo.portal.entity.form.Verifiable;
public class NamespaceIdentifer implements Verifiable { public class NamespaceIdentifier implements Verifiable {
private String appId; private String appId;
private String env; private String env;
private String clusterName; private String clusterName;
...@@ -51,10 +51,10 @@ public class NamespaceIdentifer implements Verifiable { ...@@ -51,10 +51,10 @@ public class NamespaceIdentifer implements Verifiable {
@Override @Override
public String toString() { public String toString() {
return "NamespaceIdentifer{" + return "NamespaceIdentifer{" +
"appId='" + appId + '\'' + "appId='" + appId + '\'' +
", env='" + env + '\'' + ", env='" + env + '\'' +
", clusterName='" + clusterName + '\'' + ", clusterName='" + clusterName + '\'' +
", namespaceName='" + namespaceName + '\'' + ", namespaceName='" + namespaceName + '\'' +
'}'; '}';
} }
} }
package com.ctrip.framework.apollo.portal.entity.vo; package com.ctrip.framework.apollo.portal.entity.vo;
import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
...@@ -70,7 +71,7 @@ public class NamespaceVO { ...@@ -70,7 +71,7 @@ public class NamespaceVO {
this.comment = comment; this.comment = comment;
} }
public static class ItemVO{ public static class ItemVO {
private ItemDTO item; private ItemDTO item;
private boolean isModified; private boolean isModified;
private boolean isDeleted; private boolean isDeleted;
...@@ -118,7 +119,6 @@ public class NamespaceVO { ...@@ -118,7 +119,6 @@ public class NamespaceVO {
} }
} }
} }
package com.ctrip.framework.apollo.portal.enums; package com.ctrip.framework.apollo.portal.enums;
public enum ChangeType { public enum ChangeType {
ADDED, MODIFIED, DELETED ADDED, MODIFIED, DELETED
} }
package com.ctrip.framework.apollo.portal.listener; package com.ctrip.framework.apollo.portal.listener;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.dto.AppDTO; import com.ctrip.framework.apollo.common.dto.AppDTO;
import com.ctrip.framework.apollo.common.dto.AppNamespaceDTO; import com.ctrip.framework.apollo.common.dto.AppNamespaceDTO;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.PortalSettings; import com.ctrip.framework.apollo.portal.PortalSettings;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
...@@ -43,7 +43,7 @@ public class CreationListener { ...@@ -43,7 +43,7 @@ public class CreationListener {
} }
@EventListener @EventListener
public void onAppNamespaceCreationEvent(AppNamespaceCreationEvent event){ public void onAppNamespaceCreationEvent(AppNamespaceCreationEvent event) {
AppNamespaceDTO appNamespace = BeanUtils.transfrom(AppNamespaceDTO.class, event.getAppNamespace()); AppNamespaceDTO appNamespace = BeanUtils.transfrom(AppNamespaceDTO.class, event.getAppNamespace());
List<Env> envs = portalSettings.getActiveEnvs(); List<Env> envs = portalSettings.getActiveEnvs();
for (Env env : envs) { for (Env env : envs) {
......
...@@ -6,7 +6,7 @@ import org.springframework.data.repository.PagingAndSortingRepository; ...@@ -6,7 +6,7 @@ import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List; import java.util.List;
public interface AppNamespaceRepository extends PagingAndSortingRepository<AppNamespace, Long>{ public interface AppNamespaceRepository extends PagingAndSortingRepository<AppNamespace, Long> {
AppNamespace findByAppIdAndName(String appId, String namespaceName); AppNamespace findByAppIdAndName(String appId, String namespaceName);
......
...@@ -18,10 +18,7 @@ public interface PermissionRepository extends PagingAndSortingRepository<Permiss ...@@ -18,10 +18,7 @@ public interface PermissionRepository extends PagingAndSortingRepository<Permiss
/** /**
* find permissions by permission types and targetId * find permissions by permission types and targetId
* @param permissionTypes
* @param targetId
* @return
*/ */
List<Permission> findByPermissionTypeInAndTargetId(Collection<String> permissionTypes, List<Permission> findByPermissionTypeInAndTargetId(Collection<String> permissionTypes,
String targetId); String targetId);
} }
...@@ -10,8 +10,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; ...@@ -10,8 +10,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
public interface RoleRepository extends PagingAndSortingRepository<Role, Long> { public interface RoleRepository extends PagingAndSortingRepository<Role, Long> {
/** /**
* find role by role name * find role by role name
* @param roleName
* @return
*/ */
Role findTopByRoleName(String roleName); Role findTopByRoleName(String roleName);
} }
...@@ -6,7 +6,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; ...@@ -6,7 +6,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
...@@ -14,23 +13,16 @@ import java.util.Set; ...@@ -14,23 +13,16 @@ import java.util.Set;
public interface UserRoleRepository extends PagingAndSortingRepository<UserRole, Long> { public interface UserRoleRepository extends PagingAndSortingRepository<UserRole, Long> {
/** /**
* find user roles by userId * find user roles by userId
* @param userId
* @return
*/ */
List<UserRole> findByUserId(String userId); List<UserRole> findByUserId(String userId);
/** /**
* find user roles by roleId * find user roles by roleId
* @param roleId
* @return
*/ */
List<UserRole> findByRoleId(long roleId); List<UserRole> findByRoleId(long roleId);
/** /**
* find user roles by userIds and roleId * find user roles by userIds and roleId
* @param userId
* @param roleId
* @return
*/ */
List<UserRole> findByUserIdInAndRoleId(Collection<String> userId, long roleId); List<UserRole> findByUserIdInAndRoleId(Collection<String> userId, long roleId);
} }
package com.ctrip.framework.apollo.portal.service; package com.ctrip.framework.apollo.portal.service;
import com.ctrip.framework.apollo.common.entity.AppNamespace; import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.exception.ServiceException; import com.ctrip.framework.apollo.common.exception.ServiceException;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.repository.AppNamespaceRepository; import com.ctrip.framework.apollo.portal.repository.AppNamespaceRepository;
......
...@@ -2,22 +2,12 @@ package com.ctrip.framework.apollo.portal.service; ...@@ -2,22 +2,12 @@ package com.ctrip.framework.apollo.portal.service;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import java.util.Collections; import com.ctrip.framework.apollo.common.dto.AppDTO;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.HttpStatusCodeException;
import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.utils.BeanUtils; import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.utils.ExceptionUtils; import com.ctrip.framework.apollo.common.utils.ExceptionUtils;
import com.ctrip.framework.apollo.common.dto.AppDTO;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.constant.CatEventType; import com.ctrip.framework.apollo.portal.constant.CatEventType;
...@@ -25,6 +15,16 @@ import com.ctrip.framework.apollo.portal.entity.vo.EnvClusterInfo; ...@@ -25,6 +15,16 @@ import com.ctrip.framework.apollo.portal.entity.vo.EnvClusterInfo;
import com.ctrip.framework.apollo.portal.repository.AppRepository; import com.ctrip.framework.apollo.portal.repository.AppRepository;
import com.dianping.cat.Cat; import com.dianping.cat.Cat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.HttpStatusCodeException;
import java.util.Collections;
import java.util.List;
@Service @Service
public class AppService { public class AppService {
...@@ -49,14 +49,14 @@ public class AppService { ...@@ -49,14 +49,14 @@ public class AppService {
public List<App> findAll() { public List<App> findAll() {
Iterable<App> apps = appRepository.findAll(); Iterable<App> apps = appRepository.findAll();
if (apps == null) { if (apps == null) {
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
return Lists.newArrayList((apps)); return Lists.newArrayList((apps));
} }
public App load(String appId) { public App load(String appId) {
App app = appRepository.findByAppId(appId); App app = appRepository.findByAppId(appId);
if (app == null){ if (app == null) {
throw new BadRequestException(String.format("app %s cant found.", appId)); throw new BadRequestException(String.format("app %s cant found.", appId));
} }
return app; return app;
......
package com.ctrip.framework.apollo.portal.service; package com.ctrip.framework.apollo.portal.service;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.common.dto.ClusterDTO; import com.ctrip.framework.apollo.common.dto.ClusterDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException; 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.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.constant.CatEventType; import com.ctrip.framework.apollo.portal.constant.CatEventType;
import com.dianping.cat.Cat; import com.dianping.cat.Cat;
...@@ -18,12 +18,12 @@ public class ClusterService { ...@@ -18,12 +18,12 @@ public class ClusterService {
@Autowired @Autowired
private AdminServiceAPI.ClusterAPI clusterAPI; private AdminServiceAPI.ClusterAPI clusterAPI;
public List<ClusterDTO> findClusters(Env env, String appId){ public List<ClusterDTO> findClusters(Env env, String appId) {
return clusterAPI.findClustersByApp(appId, env); return clusterAPI.findClustersByApp(appId, env);
} }
public ClusterDTO createCluster(Env env, ClusterDTO cluster){ public ClusterDTO createCluster(Env env, ClusterDTO cluster) {
if (!clusterAPI.isClusterUnique(cluster.getAppId(), env, cluster.getName())){ if (!clusterAPI.isClusterUnique(cluster.getAppId(), env, cluster.getName())) {
throw new BadRequestException(String.format("cluster %s already exists.", cluster.getName())); throw new BadRequestException(String.format("cluster %s already exists.", cluster.getName()));
} }
ClusterDTO clusterDTO = clusterAPI.create(env, cluster); ClusterDTO clusterDTO = clusterAPI.create(env, cluster);
......
...@@ -16,7 +16,7 @@ public class CommitService { ...@@ -16,7 +16,7 @@ public class CommitService {
@Autowired @Autowired
private AdminServiceAPI.CommitAPI commitAPI; private AdminServiceAPI.CommitAPI commitAPI;
public List<CommitDTO> find(String appId, Env env, String clusterName, String namespaceName, int page, int size){ public List<CommitDTO> find(String appId, Env env, String clusterName, String namespaceName, int page, int size) {
return commitAPI.find(appId, env, clusterName, namespaceName, page, size); return commitAPI.find(appId, env, clusterName, namespaceName, page, size);
} }
......
package com.ctrip.framework.apollo.portal.service; package com.ctrip.framework.apollo.portal.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.HttpClientErrorException;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.common.dto.ItemChangeSets; import com.ctrip.framework.apollo.common.dto.ItemChangeSets;
import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.constant.CatEventType; import com.ctrip.framework.apollo.portal.constant.CatEventType;
import com.ctrip.framework.apollo.portal.entity.vo.ItemDiffs;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceIdentifer;
import com.ctrip.framework.apollo.portal.entity.form.NamespaceTextModel; import com.ctrip.framework.apollo.portal.entity.form.NamespaceTextModel;
import com.ctrip.framework.apollo.portal.entity.vo.ItemDiffs;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceIdentifier;
import com.ctrip.framework.apollo.portal.service.txtresolver.ConfigTextResolver; import com.ctrip.framework.apollo.portal.service.txtresolver.ConfigTextResolver;
import com.dianping.cat.Cat; import com.dianping.cat.Cat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.HttpClientErrorException;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@Service @Service
public class ConfigService { public class ItemService {
@Autowired @Autowired
private UserInfoHolder userInfoHolder; private UserInfoHolder userInfoHolder;
...@@ -38,8 +38,6 @@ public class ConfigService { ...@@ -38,8 +38,6 @@ public class ConfigService {
private AdminServiceAPI.NamespaceAPI namespaceAPI; private AdminServiceAPI.NamespaceAPI namespaceAPI;
@Autowired @Autowired
private AdminServiceAPI.ItemAPI itemAPI; private AdminServiceAPI.ItemAPI itemAPI;
@Autowired
private AdminServiceAPI.ReleaseAPI releaseAPI;
@Autowired @Autowired
@Qualifier("fileTextResolver") @Qualifier("fileTextResolver")
...@@ -67,7 +65,7 @@ public class ConfigService { ...@@ -67,7 +65,7 @@ public class ConfigService {
model.getFormat() == ConfigFileFormat.Properties ? propertyResolver : fileTextResolver; model.getFormat() == ConfigFileFormat.Properties ? propertyResolver : fileTextResolver;
ItemChangeSets changeSets = resolver.resolve(namespaceId, configText, ItemChangeSets changeSets = resolver.resolve(namespaceId, configText,
itemAPI.findItems(appId, env, clusterName, namespaceName)); itemAPI.findItems(appId, env, clusterName, namespaceName));
if (changeSets.isEmpty()) { if (changeSets.isEmpty()) {
return; return;
} }
...@@ -76,7 +74,7 @@ public class ConfigService { ...@@ -76,7 +74,7 @@ public class ConfigService {
itemAPI.updateItemsByChangeSet(appId, env, clusterName, namespaceName, changeSets); itemAPI.updateItemsByChangeSet(appId, env, clusterName, namespaceName, changeSets);
Cat.logEvent(CatEventType.MODIFY_NAMESPACE_BY_TEXT, Cat.logEvent(CatEventType.MODIFY_NAMESPACE_BY_TEXT,
String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName)); String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName));
Cat.logEvent(CatEventType.MODIFY_NAMESPACE, String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName)); Cat.logEvent(CatEventType.MODIFY_NAMESPACE, String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName));
} }
...@@ -89,9 +87,11 @@ public class ConfigService { ...@@ -89,9 +87,11 @@ public class ConfigService {
} }
item.setNamespaceId(namespace.getId()); item.setNamespaceId(namespace.getId());
String username = userInfoHolder.getUser().getUserId(); if (StringUtils.isEmpty(item.getDataChangeCreatedBy())) {
item.setDataChangeCreatedBy(username); String username = userInfoHolder.getUser().getUserId();
item.setDataChangeLastModifiedBy(username); item.setDataChangeCreatedBy(username);
item.setDataChangeLastModifiedBy(username);
}
ItemDTO itemDTO = itemAPI.createItem(appId, env, clusterName, namespaceName, item); ItemDTO itemDTO = itemAPI.createItem(appId, env, clusterName, namespaceName, item);
Cat.logEvent(CatEventType.MODIFY_NAMESPACE, String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName)); Cat.logEvent(CatEventType.MODIFY_NAMESPACE, String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName));
...@@ -99,30 +99,36 @@ public class ConfigService { ...@@ -99,30 +99,36 @@ public class ConfigService {
} }
public void updateItem(String appId, Env env, String clusterName, String namespaceName, ItemDTO item) { public void updateItem(String appId, Env env, String clusterName, String namespaceName, ItemDTO item) {
String username = userInfoHolder.getUser().getUserId(); if (StringUtils.isEmpty(item.getDataChangeLastModifiedBy())) {
item.setDataChangeLastModifiedBy(username); String username = userInfoHolder.getUser().getUserId();
item.setDataChangeLastModifiedBy(username);
}
itemAPI.updateItem(appId, env, clusterName, namespaceName, item.getId(), item); itemAPI.updateItem(appId, env, clusterName, namespaceName, item.getId(), item);
} }
public void deleteItem(Env env, long itemId) { public void deleteItem(Env env, long itemId, String userId) {
itemAPI.deleteItem(env, itemId, userInfoHolder.getUser().getUserId()); itemAPI.deleteItem(env, itemId, userId);
} }
public List<ItemDTO> findItems(String appId, Env env, String clusterName, String namespaceName) { public List<ItemDTO> findItems(String appId, Env env, String clusterName, String namespaceName) {
return itemAPI.findItems(appId, env, clusterName, namespaceName); return itemAPI.findItems(appId, env, clusterName, namespaceName);
} }
public void syncItems(List<NamespaceIdentifer> comparedNamespaces, List<ItemDTO> sourceItems) { public ItemDTO loadItem(Env env, long itemId) {
return itemAPI.loadItem(env, itemId);
}
public void syncItems(List<NamespaceIdentifier> comparedNamespaces, List<ItemDTO> sourceItems) {
List<ItemDiffs> itemDiffs = compare(comparedNamespaces, sourceItems); List<ItemDiffs> itemDiffs = compare(comparedNamespaces, sourceItems);
for (ItemDiffs itemDiff : itemDiffs) { for (ItemDiffs itemDiff : itemDiffs) {
NamespaceIdentifer namespaceIdentifer = itemDiff.getNamespace(); NamespaceIdentifier namespaceIdentifier = itemDiff.getNamespace();
ItemChangeSets changeSets = itemDiff.getDiffs(); ItemChangeSets changeSets = itemDiff.getDiffs();
changeSets.setDataChangeLastModifiedBy(userInfoHolder.getUser().getUserId()); changeSets.setDataChangeLastModifiedBy(userInfoHolder.getUser().getUserId());
String appId = namespaceIdentifer.getAppId(); String appId = namespaceIdentifier.getAppId();
Env env = namespaceIdentifer.getEnv(); Env env = namespaceIdentifier.getEnv();
String clusterName = namespaceIdentifer.getClusterName(); String clusterName = namespaceIdentifier.getClusterName();
String namespaceName = namespaceIdentifer.getNamespaceName(); String namespaceName = namespaceIdentifier.getNamespaceName();
itemAPI.updateItemsByChangeSet(appId, env, clusterName, namespaceName, changeSets); itemAPI.updateItemsByChangeSet(appId, env, clusterName, namespaceName, changeSets);
...@@ -130,11 +136,11 @@ public class ConfigService { ...@@ -130,11 +136,11 @@ public class ConfigService {
} }
} }
public List<ItemDiffs> compare(List<NamespaceIdentifer> comparedNamespaces, List<ItemDTO> sourceItems) { public List<ItemDiffs> compare(List<NamespaceIdentifier> comparedNamespaces, List<ItemDTO> sourceItems) {
List<ItemDiffs> result = new LinkedList<>(); List<ItemDiffs> result = new LinkedList<>();
for (NamespaceIdentifer namespace : comparedNamespaces) { for (NamespaceIdentifier namespace : comparedNamespaces) {
ItemDiffs itemDiffs = new ItemDiffs(namespace); ItemDiffs itemDiffs = new ItemDiffs(namespace);
try { try {
...@@ -149,11 +155,11 @@ public class ConfigService { ...@@ -149,11 +155,11 @@ public class ConfigService {
return result; return result;
} }
private long getNamespaceId(NamespaceIdentifer namespaceIdentifer) { private long getNamespaceId(NamespaceIdentifier namespaceIdentifier) {
String appId = namespaceIdentifer.getAppId(); String appId = namespaceIdentifier.getAppId();
String clusterName = namespaceIdentifer.getClusterName(); String clusterName = namespaceIdentifier.getClusterName();
String namespaceName = namespaceIdentifer.getNamespaceName(); String namespaceName = namespaceIdentifier.getNamespaceName();
Env env = namespaceIdentifer.getEnv(); Env env = namespaceIdentifier.getEnv();
NamespaceDTO namespaceDTO = null; NamespaceDTO namespaceDTO = null;
try { try {
namespaceDTO = namespaceAPI.loadNamespace(appId, env, clusterName, namespaceName); namespaceDTO = namespaceAPI.loadNamespace(appId, env, clusterName, namespaceName);
...@@ -167,12 +173,12 @@ public class ConfigService { ...@@ -167,12 +173,12 @@ public class ConfigService {
return namespaceDTO.getId(); return namespaceDTO.getId();
} }
private ItemChangeSets parseChangeSets(NamespaceIdentifer namespace, List<ItemDTO> sourceItems) { private ItemChangeSets parseChangeSets(NamespaceIdentifier namespace, List<ItemDTO> sourceItems) {
ItemChangeSets changeSets = new ItemChangeSets(); ItemChangeSets changeSets = new ItemChangeSets();
List<ItemDTO> List<ItemDTO>
targetItems = targetItems =
itemAPI.findItems(namespace.getAppId(), namespace.getEnv(), itemAPI.findItems(namespace.getAppId(), namespace.getEnv(),
namespace.getClusterName(), namespace.getNamespaceName()); namespace.getClusterName(), namespace.getNamespaceName());
long namespaceId = getNamespaceId(namespace); long namespaceId = getNamespaceId(namespace);
...@@ -197,7 +203,7 @@ public class ConfigService { ...@@ -197,7 +203,7 @@ public class ConfigService {
changeSets.addCreateItem(buildItem(namespaceId, ++maxLineNum, sourceItem)); changeSets.addCreateItem(buildItem(namespaceId, ++maxLineNum, sourceItem));
} else if (isModified(sourceValue, targetItem.getValue(), sourceComment, } else if (isModified(sourceValue, targetItem.getValue(), sourceComment,
targetItem.getComment())) {//modified items targetItem.getComment())) {//modified items
targetItem.setValue(sourceValue); targetItem.setValue(sourceValue);
targetItem.setComment(sourceComment); targetItem.setComment(sourceComment);
changeSets.addUpdateItem(targetItem); changeSets.addUpdateItem(targetItem);
......
...@@ -13,7 +13,7 @@ public class NamespaceLockService { ...@@ -13,7 +13,7 @@ public class NamespaceLockService {
@Autowired @Autowired
private AdminServiceAPI.NamespaceLockAPI namespaceLockAPI; private AdminServiceAPI.NamespaceLockAPI namespaceLockAPI;
public NamespaceLockDTO getNamespaceLock(String appId, Env env, String clusterName, String namespaceName){ public NamespaceLockDTO getNamespaceLock(String appId, Env env, String clusterName, String namespaceName) {
return namespaceLockAPI.getNamespaceLockOwner(appId, env, clusterName, namespaceName); return namespaceLockAPI.getNamespaceLockOwner(appId, env, clusterName, namespaceName);
} }
......
...@@ -2,11 +2,12 @@ package com.ctrip.framework.apollo.portal.service; ...@@ -2,11 +2,12 @@ package com.ctrip.framework.apollo.portal.service;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.dto.ReleaseDTO; 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.common.utils.BeanUtils;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.core.utils.StringUtils;
...@@ -21,7 +22,6 @@ import org.slf4j.LoggerFactory; ...@@ -21,7 +22,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
...@@ -36,9 +36,9 @@ public class NamespaceService { ...@@ -36,9 +36,9 @@ public class NamespaceService {
@Autowired @Autowired
private UserInfoHolder userInfoHolder; private UserInfoHolder userInfoHolder;
@Autowired @Autowired
private AdminServiceAPI.ItemAPI itemAPI; private ItemService itemService;
@Autowired @Autowired
private AdminServiceAPI.ReleaseAPI releaseAPI; private ReleaseService releaseService;
@Autowired @Autowired
private AdminServiceAPI.NamespaceAPI namespaceAPI; private AdminServiceAPI.NamespaceAPI namespaceAPI;
@Autowired @Autowired
...@@ -53,11 +53,18 @@ public class NamespaceService { ...@@ -53,11 +53,18 @@ public class NamespaceService {
NamespaceDTO createdNamespace = namespaceAPI.createNamespace(env, namespace); NamespaceDTO createdNamespace = namespaceAPI.createNamespace(env, namespace);
Cat.logEvent(CatEventType.CREATE_NAMESPACE, Cat.logEvent(CatEventType.CREATE_NAMESPACE,
String.format("%s+%s+%s+%s", namespace.getAppId(), env, namespace.getClusterName(), String.format("%s+%s+%s+%s", namespace.getAppId(), env, namespace.getClusterName(),
namespace.getNamespaceName())); namespace.getNamespaceName()));
return createdNamespace; return createdNamespace;
} }
public NamespaceDTO loadNamespaceBaseInfo(String appId, Env env, String clusterName, String namespaceName) {
NamespaceDTO namespace = namespaceAPI.loadNamespace(appId, env, clusterName, namespaceName);
if (namespace == null) {
throw new BadRequestException("namespaces not exist");
}
return namespace;
}
/** /**
* load cluster all namespace info with items * load cluster all namespace info with items
...@@ -66,7 +73,7 @@ public class NamespaceService { ...@@ -66,7 +73,7 @@ public class NamespaceService {
List<NamespaceDTO> namespaces = namespaceAPI.findNamespaceByCluster(appId, env, clusterName); List<NamespaceDTO> namespaces = namespaceAPI.findNamespaceByCluster(appId, env, clusterName);
if (namespaces == null || namespaces.size() == 0) { if (namespaces == null || namespaces.size() == 0) {
return Collections.emptyList(); throw new BadRequestException("namespaces not exist");
} }
List<NamespaceVO> namespaceVOs = new LinkedList<>(); List<NamespaceVO> namespaceVOs = new LinkedList<>();
...@@ -78,7 +85,7 @@ public class NamespaceService { ...@@ -78,7 +85,7 @@ public class NamespaceService {
namespaceVOs.add(namespaceVO); namespaceVOs.add(namespaceVO);
} catch (Exception e) { } catch (Exception e) {
logger.error("parse namespace error. app id:{}, env:{}, clusterName:{}, namespace:{}", logger.error("parse namespace error. app id:{}, env:{}, clusterName:{}, namespace:{}",
appId, env, clusterName, namespace.getNamespaceName(), e); appId, env, clusterName, namespace.getNamespaceName(), e);
throw e; throw e;
} }
} }
...@@ -86,6 +93,14 @@ public class NamespaceService { ...@@ -86,6 +93,14 @@ public class NamespaceService {
return namespaceVOs; return namespaceVOs;
} }
public NamespaceVO loadNamespace(String appId, Env env, String clusterName, String namespaceName) {
NamespaceDTO namespace = namespaceAPI.loadNamespace(appId, env, clusterName, namespaceName);
if (namespace == null) {
throw new BadRequestException("namespaces not exist");
}
return parseNamespace(appId, env, clusterName, namespace);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private NamespaceVO parseNamespace(String appId, Env env, String clusterName, NamespaceDTO namespace) { private NamespaceVO parseNamespace(String appId, Env env, String clusterName, NamespaceDTO namespace) {
NamespaceVO namespaceVO = new NamespaceVO(); NamespaceVO namespaceVO = new NamespaceVO();
...@@ -101,13 +116,13 @@ public class NamespaceService { ...@@ -101,13 +116,13 @@ public class NamespaceService {
//latest Release //latest Release
ReleaseDTO latestRelease = null; ReleaseDTO latestRelease = null;
Map<String, String> releaseItems = new HashMap<>(); Map<String, String> releaseItems = new HashMap<>();
latestRelease = releaseAPI.loadLatestRelease(appId, env, clusterName, namespaceName); latestRelease = releaseService.loadLatestRelease(appId, env, clusterName, namespaceName);
if (latestRelease != null) { if (latestRelease != null) {
releaseItems = gson.fromJson(latestRelease.getConfigurations(), Map.class); releaseItems = gson.fromJson(latestRelease.getConfigurations(), Map.class);
} }
//not Release config items //not Release config items
List<ItemDTO> items = itemAPI.findItems(appId, env, clusterName, namespaceName); List<ItemDTO> items = itemService.findItems(appId, env, clusterName, namespaceName);
int modifiedItemCnt = 0; int modifiedItemCnt = 0;
for (ItemDTO itemDTO : items) { for (ItemDTO itemDTO : items) {
......
...@@ -2,9 +2,11 @@ package com.ctrip.framework.apollo.portal.service; ...@@ -2,9 +2,11 @@ package com.ctrip.framework.apollo.portal.service;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ctrip.framework.apollo.common.dto.ReleaseDTO; import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.constant.CatEventType; import com.ctrip.framework.apollo.portal.constant.CatEventType;
...@@ -19,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -19,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.lang.reflect.Type;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -28,8 +31,10 @@ import java.util.Set; ...@@ -28,8 +31,10 @@ import java.util.Set;
@Service @Service
public class ReleaseService { public class ReleaseService {
private static final Gson gson = new Gson(); private static final Gson gson = new Gson();
private static final Type configurationTypeReference =
new TypeToken<Map<String, String>>() {
}.getType();
@Autowired @Autowired
private UserInfoHolder userInfoHolder; private UserInfoHolder userInfoHolder;
...@@ -41,10 +46,13 @@ public class ReleaseService { ...@@ -41,10 +46,13 @@ public class ReleaseService {
Env env = model.getEnv(); Env env = model.getEnv();
String clusterName = model.getClusterName(); String clusterName = model.getClusterName();
String namespaceName = model.getNamespaceName(); String namespaceName = model.getNamespaceName();
ReleaseDTO releaseDTO = String releaseBy =
releaseAPI StringUtils.isEmpty(model.getReleasedBy()) ? userInfoHolder.getUser().getUserId() : model.getReleasedBy();
.createRelease(appId, env, clusterName, namespaceName, model.getReleaseTitle(), model.getReleaseComment()
, userInfoHolder.getUser().getUserId()); ReleaseDTO releaseDTO = releaseAPI
.createRelease(appId, env, clusterName, namespaceName, model.getReleaseTitle(), model.getReleaseComment()
, releaseBy);
Cat.logEvent(CatEventType.RELEASE_NAMESPACE, String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName)); Cat.logEvent(CatEventType.RELEASE_NAMESPACE, String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName));
return releaseDTO; return releaseDTO;
} }
...@@ -54,7 +62,7 @@ public class ReleaseService { ...@@ -54,7 +62,7 @@ public class ReleaseService {
List<ReleaseDTO> releaseDTOs = releaseAPI.findAllReleases(appId, env, clusterName, namespaceName, page, size); List<ReleaseDTO> releaseDTOs = releaseAPI.findAllReleases(appId, env, clusterName, namespaceName, page, size);
if (CollectionUtils.isEmpty(releaseDTOs)) { if (CollectionUtils.isEmpty(releaseDTOs)) {
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
List<ReleaseVO> releases = new LinkedList<>(); List<ReleaseVO> releases = new LinkedList<>();
...@@ -63,7 +71,8 @@ public class ReleaseService { ...@@ -63,7 +71,8 @@ public class ReleaseService {
release.setBaseInfo(releaseDTO); release.setBaseInfo(releaseDTO);
Set<KVEntity> kvEntities = new LinkedHashSet<>(); Set<KVEntity> kvEntities = new LinkedHashSet<>();
Set<Map.Entry> entries = gson.fromJson(releaseDTO.getConfigurations(), Map.class).entrySet(); Map<String, String> configurations = gson.fromJson(releaseDTO.getConfigurations(), configurationTypeReference);
Set<Map.Entry<String, String>> entries = configurations.entrySet();
for (Map.Entry<String, String> entry : entries) { for (Map.Entry<String, String> entry : entries) {
kvEntities.add(new KVEntity(entry.getKey(), entry.getValue())); kvEntities.add(new KVEntity(entry.getKey(), entry.getValue()));
} }
...@@ -81,6 +90,10 @@ public class ReleaseService { ...@@ -81,6 +90,10 @@ public class ReleaseService {
return releaseAPI.findActiveReleases(appId, env, clusterName, namespaceName, page, size); return releaseAPI.findActiveReleases(appId, env, clusterName, namespaceName, page, size);
} }
public ReleaseDTO loadLatestRelease(String appId, Env env, String clusterName, String namespaceName) {
return releaseAPI.loadLatestRelease(appId, env, clusterName, namespaceName);
}
public void rollback(Env env, long releaseId) { public void rollback(Env env, long releaseId) {
releaseAPI.rollback(env, releaseId, userInfoHolder.getUser().getUserId()); releaseAPI.rollback(env, releaseId, userInfoHolder.getUser().getUserId());
} }
...@@ -89,8 +102,8 @@ public class ReleaseService { ...@@ -89,8 +102,8 @@ public class ReleaseService {
ReleaseDTO firstRelease = releaseAPI.loadRelease(env, firstReleaseId); ReleaseDTO firstRelease = releaseAPI.loadRelease(env, firstReleaseId);
ReleaseDTO secondRelease = releaseAPI.loadRelease(env, secondReleaseId); ReleaseDTO secondRelease = releaseAPI.loadRelease(env, secondReleaseId);
Map<String, String> firstItems = gson.fromJson(firstRelease.getConfigurations(), Map.class); Map<String, String> firstItems = gson.fromJson(firstRelease.getConfigurations(), configurationTypeReference);
Map<String, String> secondItems = gson.fromJson(secondRelease.getConfigurations(), Map.class); Map<String, String> secondItems = gson.fromJson(secondRelease.getConfigurations(), configurationTypeReference);
ReleaseCompareResult compareResult = new ReleaseCompareResult(); ReleaseCompareResult compareResult = new ReleaseCompareResult();
...@@ -102,10 +115,10 @@ public class ReleaseService { ...@@ -102,10 +115,10 @@ public class ReleaseService {
//added //added
if (secondValue == null) { if (secondValue == null) {
compareResult.addEntityPair(ChangeType.DELETED, new KVEntity(key, firstValue), compareResult.addEntityPair(ChangeType.DELETED, new KVEntity(key, firstValue),
new KVEntity(key, secondValue)); new KVEntity(key, secondValue));
} else if (!Objects.equal(firstValue, secondValue)) { } else if (!Objects.equal(firstValue, secondValue)) {
compareResult.addEntityPair(ChangeType.MODIFIED, new KVEntity(key, firstValue), compareResult.addEntityPair(ChangeType.MODIFIED, new KVEntity(key, firstValue),
new KVEntity(key, secondValue)); new KVEntity(key, secondValue));
} }
} }
......
...@@ -33,7 +33,7 @@ public class RoleInitializationService { ...@@ -33,7 +33,7 @@ public class RoleInitializationService {
String appMasterRoleName = RoleUtils.buildAppMasterRoleName(appId); String appMasterRoleName = RoleUtils.buildAppMasterRoleName(appId);
//has created before //has created before
if (rolePermissionService.findRoleByRoleName(appMasterRoleName) != null){ if (rolePermissionService.findRoleByRoleName(appMasterRoleName) != null) {
return; return;
} }
String operaterUserId = userInfoHolder.getUser().getUserId(); String operaterUserId = userInfoHolder.getUser().getUserId();
...@@ -43,7 +43,7 @@ public class RoleInitializationService { ...@@ -43,7 +43,7 @@ public class RoleInitializationService {
//assign master role to user //assign master role to user
rolePermissionService rolePermissionService
.assignRoleToUsers(RoleUtils.buildAppMasterRoleName(appId), Sets.newHashSet(app.getOwnerName()), .assignRoleToUsers(RoleUtils.buildAppMasterRoleName(appId), Sets.newHashSet(app.getOwnerName()),
operaterUserId); operaterUserId);
initNamespaceRoles(appId, ConfigConsts.NAMESPACE_APPLICATION); initNamespaceRoles(appId, ConfigConsts.NAMESPACE_APPLICATION);
...@@ -55,13 +55,13 @@ public class RoleInitializationService { ...@@ -55,13 +55,13 @@ public class RoleInitializationService {
String modifyNamespaceRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName); String modifyNamespaceRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName);
if (rolePermissionService.findRoleByRoleName(modifyNamespaceRoleName) == null) { if (rolePermissionService.findRoleByRoleName(modifyNamespaceRoleName) == null) {
createDefaultNamespaceRole(appId, namespaceName, PermissionType.MODIFY_NAMESPACE, createDefaultNamespaceRole(appId, namespaceName, PermissionType.MODIFY_NAMESPACE,
RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName)); RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName));
} }
String releaseNamespaceRoleName = RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName); String releaseNamespaceRoleName = RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName);
if (rolePermissionService.findRoleByRoleName(releaseNamespaceRoleName) == null) { if (rolePermissionService.findRoleByRoleName(releaseNamespaceRoleName) == null) {
createDefaultNamespaceRole(appId, namespaceName, PermissionType.RELEASE_NAMESPACE, createDefaultNamespaceRole(appId, namespaceName, PermissionType.RELEASE_NAMESPACE,
RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName)); RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName));
} }
} }
......
package com.ctrip.framework.apollo.portal.service.txtresolver; package com.ctrip.framework.apollo.portal.service.txtresolver;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.common.dto.ItemChangeSets; import com.ctrip.framework.apollo.common.dto.ItemChangeSets;
import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.core.utils.StringUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
......
...@@ -35,7 +35,7 @@ public class PropertyResolver implements ConfigTextResolver { ...@@ -35,7 +35,7 @@ public class PropertyResolver implements ConfigTextResolver {
String[] newItems = configText.split(ITEM_SEPARATOR); String[] newItems = configText.split(ITEM_SEPARATOR);
if (isHasRepeatKey(newItems)){ if (isHasRepeatKey(newItems)) {
throw new BadRequestException("config text has repeat key please check."); throw new BadRequestException("config text has repeat key please check.");
} }
...@@ -71,27 +71,27 @@ public class PropertyResolver implements ConfigTextResolver { ...@@ -71,27 +71,27 @@ public class PropertyResolver implements ConfigTextResolver {
return changeSets; return changeSets;
} }
private boolean isHasRepeatKey(String[] newItems){ private boolean isHasRepeatKey(String[] newItems) {
Set<String> keys = new HashSet<>(); Set<String> keys = new HashSet<>();
int lineCounter = 1; int lineCounter = 1;
int keyCount = 0; int keyCount = 0;
for (String item: newItems){ for (String item : newItems) {
if (!isCommentItem(item) && !isBlankItem(item)){ if (!isCommentItem(item) && !isBlankItem(item)) {
keyCount++; keyCount++;
String[] kv = parseKeyValueFromItem(item); String[] kv = parseKeyValueFromItem(item);
if (kv != null) { if (kv != null) {
keys.add(kv[0]); keys.add(kv[0]);
}else { } else {
throw new BadRequestException("line:" + lineCounter + " key value must separate by '='"); throw new BadRequestException("line:" + lineCounter + " key value must separate by '='");
} }
} }
lineCounter ++; lineCounter++;
} }
return keyCount > keys.size(); return keyCount > keys.size();
} }
private String[] parseKeyValueFromItem(String item){ private String[] parseKeyValueFromItem(String item) {
int kvSeparator = item.indexOf(KV_SEPARATOR); int kvSeparator = item.indexOf(KV_SEPARATOR);
if (kvSeparator == -1) { if (kvSeparator == -1) {
return null; return null;
...@@ -118,7 +118,7 @@ public class PropertyResolver implements ConfigTextResolver { ...@@ -118,7 +118,7 @@ public class PropertyResolver implements ConfigTextResolver {
} }
private void handleNormalLine(Long namespaceId, Map<String, ItemDTO> keyMapOldItem, String newItem, private void handleNormalLine(Long namespaceId, Map<String, ItemDTO> keyMapOldItem, String newItem,
int lineCounter, ItemChangeSets changeSets) { int lineCounter, ItemChangeSets changeSets) {
String[] kv = parseKeyValueFromItem(newItem); String[] kv = parseKeyValueFromItem(newItem);
...@@ -133,17 +133,17 @@ public class PropertyResolver implements ConfigTextResolver { ...@@ -133,17 +133,17 @@ public class PropertyResolver implements ConfigTextResolver {
if (oldItem == null) {//new item if (oldItem == null) {//new item
changeSets.addCreateItem(buildNormalItem(0l, namespaceId, newKey, newValue, "", lineCounter)); changeSets.addCreateItem(buildNormalItem(0l, namespaceId, newKey, newValue, "", lineCounter));
} else if (!newValue.equals(oldItem.getValue()) || lineCounter != oldItem.getLineNum()){//update item } else if (!newValue.equals(oldItem.getValue()) || lineCounter != oldItem.getLineNum()) {//update item
changeSets.addUpdateItem( changeSets.addUpdateItem(
buildNormalItem(oldItem.getId(), namespaceId, newKey, newValue, oldItem.getComment(), buildNormalItem(oldItem.getId(), namespaceId, newKey, newValue, oldItem.getComment(),
lineCounter)); lineCounter));
} }
keyMapOldItem.remove(newKey); keyMapOldItem.remove(newKey);
} }
private boolean isCommentItem(ItemDTO item) { private boolean isCommentItem(ItemDTO item) {
return item != null && "".equals(item.getKey()) return item != null && "".equals(item.getKey())
&& (item.getComment().startsWith("#") || item.getComment().startsWith("!")); && (item.getComment().startsWith("#") || item.getComment().startsWith("!"));
} }
private boolean isCommentItem(String line) { private boolean isCommentItem(String line) {
......
...@@ -9,38 +9,39 @@ public class RoleUtils { ...@@ -9,38 +9,39 @@ public class RoleUtils {
private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR); private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR);
public static String buildAppMasterRoleName(String appId){ public static String buildAppMasterRoleName(String appId) {
return STRING_JOINER.join(RoleType.MASTER, appId); return STRING_JOINER.join(RoleType.MASTER, appId);
} }
public static String buildAppRoleName(String appId, String roleType){ public static String buildAppRoleName(String appId, String roleType) {
return STRING_JOINER.join(roleType, appId); return STRING_JOINER.join(roleType, appId);
} }
public static String buildModifyNamespaceRoleName(String appId, String namespaceName){
public static String buildModifyNamespaceRoleName(String appId, String namespaceName) {
return STRING_JOINER.join(RoleType.MODIFY_NAMESPACE, appId, namespaceName); return STRING_JOINER.join(RoleType.MODIFY_NAMESPACE, appId, namespaceName);
} }
public static String buildModifyDefaultNamespaceRoleName(String appId){ public static String buildModifyDefaultNamespaceRoleName(String appId) {
return STRING_JOINER.join(RoleType.MODIFY_NAMESPACE, appId, ConfigConsts.NAMESPACE_APPLICATION); return STRING_JOINER.join(RoleType.MODIFY_NAMESPACE, appId, ConfigConsts.NAMESPACE_APPLICATION);
} }
public static String buildReleaseNamespaceRoleName(String appId, String namespaceName){ public static String buildReleaseNamespaceRoleName(String appId, String namespaceName) {
return STRING_JOINER.join(RoleType.RELEASE_NAMESPACE, appId, namespaceName); return STRING_JOINER.join(RoleType.RELEASE_NAMESPACE, appId, namespaceName);
} }
public static String buildNamespaceRoleName(String appId, String namespaceName, String roleType){ public static String buildNamespaceRoleName(String appId, String namespaceName, String roleType) {
return STRING_JOINER.join(roleType, appId, namespaceName); return STRING_JOINER.join(roleType, appId, namespaceName);
} }
public static String buildReleaseDefaultNamespaceRoleName(String appId){ public static String buildReleaseDefaultNamespaceRoleName(String appId) {
return STRING_JOINER.join(RoleType.RELEASE_NAMESPACE, appId, ConfigConsts.NAMESPACE_APPLICATION); return STRING_JOINER.join(RoleType.RELEASE_NAMESPACE, appId, ConfigConsts.NAMESPACE_APPLICATION);
} }
public static String buildNamespaceTargetId(String appId, String namespaceName){ public static String buildNamespaceTargetId(String appId, String namespaceName) {
return STRING_JOINER.join(appId, namespaceName); return STRING_JOINER.join(appId, namespaceName);
} }
public static String buildDefaultNamespaceTargetId(String appId){ public static String buildDefaultNamespaceTargetId(String appId) {
return STRING_JOINER.join(appId, ConfigConsts.NAMESPACE_APPLICATION); return STRING_JOINER.join(appId, ConfigConsts.NAMESPACE_APPLICATION);
} }
......
package com.ctrip.framework.apollo.openapi.filter;
import com.ctrip.framework.apollo.openapi.util.ConsumerAuthUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static org.junit.Assert.*;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith(MockitoJUnitRunner.class)
public class ConsumerAuthenticationFilterTest {
private ConsumerAuthenticationFilter authenticationFilter;
@Mock
private ConsumerAuthUtil consumerAuthUtil;
@Mock
private HttpServletRequest request;
@Mock
private HttpServletResponse response;
@Mock
private FilterChain filterChain;
@Before
public void setUp() throws Exception {
authenticationFilter = new ConsumerAuthenticationFilter(consumerAuthUtil);
}
@Test
public void testAuthSuccessfully() throws Exception {
String someToken = "someToken";
Long someConsumerId = 1L;
when(request.getHeader("Authorization")).thenReturn(someToken);
when(consumerAuthUtil.getConsumerId(someToken)).thenReturn(someConsumerId);
authenticationFilter.doFilter(request, response, filterChain);
verify(consumerAuthUtil, times(1)).storeConsumerId(request, someConsumerId);
verify(filterChain, times(1)).doFilter(request, response);
}
@Test
public void testAuthFailed() throws Exception {
String someInvalidToken = "someInvalidToken";
when(request.getHeader("Authorization")).thenReturn(someInvalidToken);
when(consumerAuthUtil.getConsumerId(someInvalidToken)).thenReturn(null);
authenticationFilter.doFilter(request, response, filterChain);
verify(response, times(1)).sendError(eq(HttpServletResponse.SC_UNAUTHORIZED), anyString());
verify(consumerAuthUtil, never()).storeConsumerId(eq(request), anyLong());
verify(filterChain, never()).doFilter(request, response);
}
}
\ No newline at end of file
package com.ctrip.framework.apollo.openapi.service;
import com.ctrip.framework.apollo.portal.AbstractIntegrationTest;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.jdbc.Sql;
import static org.junit.Assert.*;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ConsumerRolePermissionServiceTest extends AbstractIntegrationTest {
@Autowired
private ConsumerRolePermissionService consumerRolePermissionService;
@Before
public void setUp() throws Exception {
}
@Test
@Sql(scripts = "/sql/permission/insert-test-roles.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/permission/insert-test-permissions.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/permission/insert-test-consumerroles.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/permission/insert-test-rolepermissions.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testConsumerHasPermission() throws Exception {
String someTargetId = "someTargetId";
String anotherTargetId = "anotherTargetId";
String somePermissionType = "somePermissionType";
String anotherPermissionType = "anotherPermissionType";
long someConsumerId = 1;
long anotherConsumerId = 2;
long someConsumerWithNoPermission = 3;
assertTrue(consumerRolePermissionService.consumerHasPermission(someConsumerId, somePermissionType, someTargetId));
assertTrue(consumerRolePermissionService.consumerHasPermission(someConsumerId, anotherPermissionType, anotherTargetId));
assertTrue(consumerRolePermissionService.consumerHasPermission(anotherConsumerId, somePermissionType, someTargetId));
assertTrue(consumerRolePermissionService.consumerHasPermission(anotherConsumerId, anotherPermissionType, anotherTargetId));
assertFalse(consumerRolePermissionService.consumerHasPermission(someConsumerWithNoPermission, somePermissionType, someTargetId));
assertFalse(consumerRolePermissionService.consumerHasPermission(someConsumerWithNoPermission, anotherPermissionType, anotherTargetId));
}
}
\ No newline at end of file
package com.ctrip.framework.apollo.openapi.service;
import com.ctrip.framework.apollo.openapi.entity.Consumer;
import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
import com.ctrip.framework.apollo.openapi.repository.ConsumerRepository;
import com.ctrip.framework.apollo.openapi.repository.ConsumerTokenRepository;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith(MockitoJUnitRunner.class)
public class ConsumerServiceTest {
private ConsumerService consumerService;
@Mock
private ConsumerTokenRepository consumerTokenRepository;
@Mock
private ConsumerRepository consumerRepository;
@Mock
private ServerConfigService serverConfigService;
private String someTokenSalt;
@Before
public void setUp() throws Exception {
consumerService = spy(new ConsumerService());
ReflectionTestUtils.setField(consumerService, "consumerTokenRepository",
consumerTokenRepository);
ReflectionTestUtils.setField(consumerService, "consumerRepository",
consumerRepository);
ReflectionTestUtils.setField(consumerService, "serverConfigService",
serverConfigService);
someTokenSalt = "someTokenSalt";
when(serverConfigService.getValue(eq(ConsumerService.TOKEN_SALT_KEY), anyString())).thenReturn(someTokenSalt);
consumerService.afterPropertiesSet();
}
@Test
public void testGetConsumerId() throws Exception {
String someToken = "someToken";
long someConsumerId = 1;
ConsumerToken someConsumerToken = new ConsumerToken();
someConsumerToken.setConsumerId(someConsumerId);
when(consumerTokenRepository.findTopByTokenAndExpiresAfter(eq(someToken), any(Date.class)))
.thenReturn(someConsumerToken);
assertEquals(someConsumerId, consumerService.getConsumerIdByToken(someToken).longValue());
}
@Test
public void testGetConsumerIdWithNullToken() throws Exception {
Long consumerId = consumerService.getConsumerIdByToken(null);
assertNull(consumerId);
verify(consumerTokenRepository, never()).findTopByTokenAndExpiresAfter(anyString(), any(Date
.class));
}
@Test
public void testGetConsumerByConsumerId() throws Exception {
long someConsumerId = 1;
Consumer someConsumer = mock(Consumer.class);
when(consumerRepository.findOne(someConsumerId)).thenReturn(someConsumer);
assertEquals(someConsumer, consumerService.getConsumerByConsumerId(someConsumerId));
verify(consumerRepository, times(1)).findOne(someConsumerId);
}
@Test
public void testCreateConsumerToken() throws Exception {
ConsumerToken someConsumerToken = mock(ConsumerToken.class);
ConsumerToken savedConsumerToken = mock(ConsumerToken.class);
when(consumerTokenRepository.save(someConsumerToken)).thenReturn(savedConsumerToken);
assertEquals(savedConsumerToken, consumerService.createConsumerToken(someConsumerToken));
}
@Test
public void testGenerateConsumerToken() throws Exception {
String someConsumerAppId = "100003171";
Date generationTime = new GregorianCalendar(2016, Calendar.AUGUST, 9, 12, 10, 50).getTime();
String tokenSalt = "apollo";
assertEquals("d0da35292dd5079eeb73cc3a5f7c0759afabd806", consumerService
.generateConsumerToken(someConsumerAppId, generationTime, tokenSalt));
}
@Test
public void testGenerateAndEnrichConsumerToken() throws Exception {
String someConsumerAppId = "someAppId";
long someConsumerId = 1;
String someToken = "someToken";
Date generationTime = new Date();
Consumer consumer = mock(Consumer.class);
when(consumerRepository.findOne(someConsumerId)).thenReturn(consumer);
when(consumer.getAppId()).thenReturn(someConsumerAppId);
when(consumerService.generateConsumerToken(someConsumerAppId, generationTime, someTokenSalt))
.thenReturn(someToken);
ConsumerToken consumerToken = new ConsumerToken();
consumerToken.setConsumerId(someConsumerId);
consumerToken.setDataChangeCreatedTime(generationTime);
consumerService.generateAndEnrichConsumerToken(consumerToken);
assertEquals(someToken, consumerToken.getToken());
}
@Test(expected = IllegalStateException.class)
public void testGenerateAndEnrichConsumerTokenWithConsumerNotFound() throws Exception {
long someConsumerIdNotExist = 1;
ConsumerToken consumerToken = new ConsumerToken();
consumerToken.setConsumerId(someConsumerIdNotExist);
when(consumerRepository.findOne(someConsumerIdNotExist)).thenReturn(null);
consumerService.generateAndEnrichConsumerToken(consumerToken);
}
}
\ No newline at end of file
package com.ctrip.framework.apollo.openapi.util;
import com.ctrip.framework.apollo.openapi.service.ConsumerService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import javax.servlet.http.HttpServletRequest;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith(MockitoJUnitRunner.class)
public class ConsumerAuthUtilTest {
private ConsumerAuthUtil consumerAuthUtil;
@Mock
private ConsumerService consumerService;
@Mock
private HttpServletRequest request;
@Before
public void setUp() throws Exception {
consumerAuthUtil = new ConsumerAuthUtil();
ReflectionTestUtils.setField(consumerAuthUtil, "consumerService", consumerService);
}
@Test
public void testGetConsumerId() throws Exception {
String someToken = "someToken";
Long someConsumerId = 1L;
when(consumerService.getConsumerIdByToken(someToken)).thenReturn(someConsumerId);
assertEquals(someConsumerId, consumerAuthUtil.getConsumerId(someToken));
verify(consumerService, times(1)).getConsumerIdByToken(someToken);
}
@Test
public void testStoreConsumerId() throws Exception {
long someConsumerId = 1L;
consumerAuthUtil.storeConsumerId(request, someConsumerId);
verify(request, times(1)).setAttribute(ConsumerAuthUtil.CONSUMER_ID, someConsumerId);
}
@Test
public void testRetrieveConsumerId() throws Exception {
long someConsumerId = 1;
when(request.getAttribute(ConsumerAuthUtil.CONSUMER_ID)).thenReturn(someConsumerId);
assertEquals(someConsumerId, consumerAuthUtil.retrieveConsumerId(request));
verify(request, times(1)).getAttribute(ConsumerAuthUtil.CONSUMER_ID);
}
@Test(expected = IllegalStateException.class)
public void testRetrieveConsumerIdWithConsumerIdNotSet() throws Exception {
consumerAuthUtil.retrieveConsumerId(request);
}
@Test(expected = IllegalStateException.class)
public void testRetrieveConsumerIdWithConsumerIdInvalid() throws Exception {
String someInvalidConsumerId = "abc";
when(request.getAttribute(ConsumerAuthUtil.CONSUMER_ID)).thenReturn(someInvalidConsumerId);
consumerAuthUtil.retrieveConsumerId(request);
}
}
\ No newline at end of file
package com.ctrip.framework.apollo.portal; package com.ctrip.framework.apollo.portal;
import com.ctrip.framework.apollo.PortalApplication;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.SpringApplicationConfiguration;
......
package com.ctrip.framework.apollo.portal; package com.ctrip.framework.apollo.portal;
import com.ctrip.framework.apollo.openapi.filter.ConsumerAuthenticationFilterTest;
import com.ctrip.framework.apollo.openapi.service.ConsumerRolePermissionServiceTest;
import com.ctrip.framework.apollo.openapi.service.ConsumerServiceTest;
import com.ctrip.framework.apollo.openapi.util.ConsumerAuthUtilTest;
import com.ctrip.framework.apollo.portal.controller.ConsumerControllerTest;
import com.ctrip.framework.apollo.portal.service.AppNamespaceServiceTest; import com.ctrip.framework.apollo.portal.service.AppNamespaceServiceTest;
import com.ctrip.framework.apollo.portal.service.ConfigServiceTest; import com.ctrip.framework.apollo.portal.service.ConfigServiceTest;
import com.ctrip.framework.apollo.portal.service.NamespaceServiceTest; import com.ctrip.framework.apollo.portal.service.NamespaceServiceTest;
...@@ -18,7 +23,9 @@ import org.junit.runners.Suite.SuiteClasses; ...@@ -18,7 +23,9 @@ import org.junit.runners.Suite.SuiteClasses;
ConfigServiceTest.class, PropertyResolverTest.class, ConfigServiceTest.class, PropertyResolverTest.class,
NamespaceServiceTest.class, ServiceExceptionTest.class, RolePermissionServiceTest.class, NamespaceServiceTest.class, ServiceExceptionTest.class, RolePermissionServiceTest.class,
AppNamespaceServiceTest.class, RoleInitializationServiceTest.class, FileTextResolverTest.class, AppNamespaceServiceTest.class, RoleInitializationServiceTest.class, FileTextResolverTest.class,
RetryableRestTemplateTest.class RetryableRestTemplateTest.class, ConsumerRolePermissionServiceTest.class,
ConsumerAuthenticationFilterTest.class, ConsumerAuthUtilTest.class, ConsumerServiceTest.class,
ConsumerControllerTest.class
}) })
public class AllTests { public class AllTests {
......
...@@ -11,77 +11,68 @@ import java.util.LinkedHashMap; ...@@ -11,77 +11,68 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.HttpStatusCodeException; import org.springframework.web.client.HttpStatusCodeException;
import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.common.utils.ExceptionUtils;
import com.ctrip.framework.apollo.common.dto.AppDTO;
import com.ctrip.framework.apollo.common.exception.ServiceException; import com.ctrip.framework.apollo.common.exception.ServiceException;
import com.ctrip.framework.apollo.portal.controller.AppController; import com.ctrip.framework.apollo.portal.controller.AppController;
import com.ctrip.framework.apollo.portal.service.UserService; import com.ctrip.framework.apollo.portal.service.UserService;
import com.google.gson.Gson; import com.google.gson.Gson;
public class ServiceExceptionTest extends AbstractIntegrationTest { public class ServiceExceptionTest extends AbstractUnitTest {
@Autowired @InjectMocks
private AppController appController; private AppController appController;
@Mock @Mock
private UserService userService; private UserService userService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(appController, "userService", userService);
}
private String getBaseAppUrl() { @Test
return "http://localhost:" + port + "/apps"; public void testAdminServiceException() {
} String errorMsg = "No available admin service";
String errorCode = "errorCode";
String status = "500";
@Test Map<String, Object> errorAttributes = new LinkedHashMap<>();
public void testAdminServiceException() { errorAttributes.put("status", status);
Map<String, Object> errorAttributes = new LinkedHashMap<>(); errorAttributes.put("message", errorMsg);
errorAttributes.put("status", 500); errorAttributes.put("timestamp",
errorAttributes.put("message", "No available admin service"); LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
errorAttributes.put("timestamp", errorAttributes.put("exception", ServiceException.class.getName());
LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); errorAttributes.put("errorCode", errorCode);
errorAttributes.put("exception", ServiceException.class.getName());
errorAttributes.put("errorCode", "8848");
HttpStatusCodeException adminException = HttpStatusCodeException adminException =
new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, "admin server error", new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, "admin server error",
new Gson().toJson(errorAttributes).getBytes(), Charset.defaultCharset()); new Gson().toJson(errorAttributes).getBytes(), Charset.defaultCharset());
when(userService.findByUserId(any(String.class))).thenThrow(adminException); when(userService.findByUserId(any(String.class))).thenThrow(adminException);
App app = generateSampleApp(); App app = generateSampleApp();
try { try {
restTemplate.postForEntity(getBaseAppUrl(), app, AppDTO.class); appController.create(app);
} catch (HttpStatusCodeException e) { } catch (HttpStatusCodeException e) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Map<String, String> attr = new Gson().fromJson(e.getResponseBodyAsString(), Map.class); Map<String, String> attr = new Gson().fromJson(e.getResponseBodyAsString(), Map.class);
Assert.assertEquals("500 admin server error", attr.get("message")); Assert.assertEquals(errorMsg, attr.get("message"));
Assert.assertEquals(500.0, attr.get("status")); Assert.assertEquals(errorCode, attr.get("errorCode"));
} Assert.assertEquals(status, attr.get("status"));
} }
}
private App generateSampleApp() { private App generateSampleApp() {
App app = new App(); App app = new App();
app.setAppId("someAppId"); app.setAppId("someAppId");
app.setName("someName"); app.setName("someName");
app.setOrgId("someOrgId"); app.setOrgId("someOrgId");
app.setOrgName("someOrgNam"); app.setOrgName("someOrgNam");
app.setOwnerName("someOwner"); app.setOwnerName("someOwner");
app.setOwnerEmail("someOwner@ctrip.com"); app.setOwnerEmail("someOwner@ctrip.com");
return app; return app;
} }
} }
package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
import com.ctrip.framework.apollo.openapi.service.ConsumerService;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Date;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith(MockitoJUnitRunner.class)
public class ConsumerControllerTest {
private ConsumerController consumerController;
@Mock
private ConsumerService consumerService;
@Mock
private UserInfoHolder userInfoHolder;
@Before
public void setUp() throws Exception {
consumerController = new ConsumerController();
ReflectionTestUtils.setField(consumerController, "consumerService", consumerService);
ReflectionTestUtils.setField(consumerController, "userInfoHolder", userInfoHolder);
}
@Test
public void testCreateConsumerToken() throws Exception {
UserInfo userInfo = mock(UserInfo.class);
String someUserId = "someUser";
ConsumerToken consumerToken = mock(ConsumerToken.class);
long someConsumerId = 1;
Date someDateExpires = new Date();
when(userInfo.getUserId()).thenReturn(someUserId);
when(userInfoHolder.getUser()).thenReturn(userInfo);
when(consumerService.createConsumerToken(any(ConsumerToken.class))).thenReturn(consumerToken);
assertEquals(consumerToken, consumerController.createConsumerToken(someConsumerId, someDateExpires));
verify(consumerService, times(1)).generateAndEnrichConsumerToken(any(ConsumerToken.class));
verify(consumerService, times(1)).createConsumerToken(any(ConsumerToken.class));
}
}
\ No newline at end of file
...@@ -10,7 +10,7 @@ import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; ...@@ -10,7 +10,7 @@ import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.entity.po.UserInfo; import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
import com.ctrip.framework.apollo.portal.entity.vo.ItemDiffs; import com.ctrip.framework.apollo.portal.entity.vo.ItemDiffs;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceIdentifer; import com.ctrip.framework.apollo.portal.entity.vo.NamespaceIdentifier;
import com.ctrip.framework.apollo.portal.entity.form.NamespaceTextModel; import com.ctrip.framework.apollo.portal.entity.form.NamespaceTextModel;
import com.ctrip.framework.apollo.portal.service.txtresolver.PropertyResolver; import com.ctrip.framework.apollo.portal.service.txtresolver.PropertyResolver;
...@@ -44,7 +44,7 @@ public class ConfigServiceTest { ...@@ -44,7 +44,7 @@ public class ConfigServiceTest {
private UserInfoHolder userInfoHolder; private UserInfoHolder userInfoHolder;
@InjectMocks @InjectMocks
private ConfigService configService; private ItemService configService;
@Before @Before
public void setup() { public void setup() {
...@@ -100,7 +100,7 @@ public class ConfigServiceTest { ...@@ -100,7 +100,7 @@ public class ConfigServiceTest {
String appId = "6666", env = "LOCAL", clusterName = ConfigConsts.CLUSTER_NAME_DEFAULT, String appId = "6666", env = "LOCAL", clusterName = ConfigConsts.CLUSTER_NAME_DEFAULT,
namespaceName = ConfigConsts.NAMESPACE_APPLICATION; namespaceName = ConfigConsts.NAMESPACE_APPLICATION;
List<NamespaceIdentifer> namespaceIdentifers = generateNamespaceIdentifer(appId, env, clusterName, namespaceName); List<NamespaceIdentifier> namespaceIdentifiers = generateNamespaceIdentifer(appId, env, clusterName, namespaceName);
NamespaceDTO namespaceDTO = generateNamespaceDTO(appId, clusterName, namespaceName); NamespaceDTO namespaceDTO = generateNamespaceDTO(appId, clusterName, namespaceName);
when(namespaceAPI.loadNamespace(appId, Env.valueOf(env), clusterName, namespaceName)).thenReturn(namespaceDTO); when(namespaceAPI.loadNamespace(appId, Env.valueOf(env), clusterName, namespaceName)).thenReturn(namespaceDTO);
...@@ -110,7 +110,7 @@ public class ConfigServiceTest { ...@@ -110,7 +110,7 @@ public class ConfigServiceTest {
userInfo.setUserId("test"); userInfo.setUserId("test");
when(userInfoHolder.getUser()).thenReturn(userInfo); when(userInfoHolder.getUser()).thenReturn(userInfo);
List<ItemDiffs> itemDiffses = configService.compare(namespaceIdentifers, sourceItems); List<ItemDiffs> itemDiffses = configService.compare(namespaceIdentifiers, sourceItems);
assertEquals(1,itemDiffses.size()); assertEquals(1,itemDiffses.size());
ItemDiffs itemDiffs = itemDiffses.get(0); ItemDiffs itemDiffs = itemDiffses.get(0);
...@@ -141,7 +141,7 @@ public class ConfigServiceTest { ...@@ -141,7 +141,7 @@ public class ConfigServiceTest {
String appId = "6666", env = "LOCAL", clusterName = ConfigConsts.CLUSTER_NAME_DEFAULT, String appId = "6666", env = "LOCAL", clusterName = ConfigConsts.CLUSTER_NAME_DEFAULT,
namespaceName = ConfigConsts.NAMESPACE_APPLICATION; namespaceName = ConfigConsts.NAMESPACE_APPLICATION;
List<NamespaceIdentifer> namespaceIdentifers = generateNamespaceIdentifer(appId, env, clusterName, namespaceName); List<NamespaceIdentifier> namespaceIdentifiers = generateNamespaceIdentifer(appId, env, clusterName, namespaceName);
NamespaceDTO namespaceDTO = generateNamespaceDTO(appId, clusterName, namespaceName); NamespaceDTO namespaceDTO = generateNamespaceDTO(appId, clusterName, namespaceName);
when(namespaceAPI.loadNamespace(appId, Env.valueOf(env), clusterName, namespaceName)).thenReturn(namespaceDTO); when(namespaceAPI.loadNamespace(appId, Env.valueOf(env), clusterName, namespaceName)).thenReturn(namespaceDTO);
...@@ -151,7 +151,7 @@ public class ConfigServiceTest { ...@@ -151,7 +151,7 @@ public class ConfigServiceTest {
userInfo.setUserId("test"); userInfo.setUserId("test");
when(userInfoHolder.getUser()).thenReturn(userInfo); when(userInfoHolder.getUser()).thenReturn(userInfo);
List<ItemDiffs> itemDiffses = configService.compare(namespaceIdentifers, sourceItems); List<ItemDiffs> itemDiffses = configService.compare(namespaceIdentifiers, sourceItems);
assertEquals(1, itemDiffses.size()); assertEquals(1, itemDiffses.size());
ItemDiffs itemDiffs = itemDiffses.get(0); ItemDiffs itemDiffs = itemDiffses.get(0);
...@@ -161,11 +161,11 @@ public class ConfigServiceTest { ...@@ -161,11 +161,11 @@ public class ConfigServiceTest {
assertEquals(2, changeSets.getUpdateItems().size()); assertEquals(2, changeSets.getUpdateItems().size());
assertEquals(1, changeSets.getCreateItems().size()); assertEquals(1, changeSets.getCreateItems().size());
NamespaceIdentifer namespaceIdentifer = itemDiffs.getNamespace(); NamespaceIdentifier namespaceIdentifier = itemDiffs.getNamespace();
assertEquals(appId, namespaceIdentifer.getAppId()); assertEquals(appId, namespaceIdentifier.getAppId());
assertEquals(Env.valueOf("LOCAL"), namespaceIdentifer.getEnv()); assertEquals(Env.valueOf("LOCAL"), namespaceIdentifier.getEnv());
assertEquals(clusterName, namespaceIdentifer.getClusterName()); assertEquals(clusterName, namespaceIdentifier.getClusterName());
assertEquals(namespaceName, namespaceIdentifer.getNamespaceName()); assertEquals(namespaceName, namespaceIdentifier.getNamespaceName());
ItemDTO createdItem = changeSets.getCreateItems().get(0); ItemDTO createdItem = changeSets.getCreateItems().get(0);
assertEquals("newKey", createdItem.getKey()); assertEquals("newKey", createdItem.getKey());
...@@ -198,8 +198,8 @@ public class ConfigServiceTest { ...@@ -198,8 +198,8 @@ public class ConfigServiceTest {
return namespaceDTO; return namespaceDTO;
} }
private List<NamespaceIdentifer> generateNamespaceIdentifer(String appId, String env, String clusterName, String namespaceName){ private List<NamespaceIdentifier> generateNamespaceIdentifer(String appId, String env, String clusterName, String namespaceName){
NamespaceIdentifer targetNamespace = new NamespaceIdentifer(); NamespaceIdentifier targetNamespace = new NamespaceIdentifier();
targetNamespace.setAppId(appId); targetNamespace.setAppId(appId);
targetNamespace.setEnv(env); targetNamespace.setEnv(env);
targetNamespace.setClusterName(clusterName); targetNamespace.setClusterName(clusterName);
......
...@@ -30,9 +30,9 @@ public class NamespaceServiceTest { ...@@ -30,9 +30,9 @@ public class NamespaceServiceTest {
@Mock @Mock
private AdminServiceAPI.NamespaceAPI namespaceAPI; private AdminServiceAPI.NamespaceAPI namespaceAPI;
@Mock @Mock
private AdminServiceAPI.ReleaseAPI releaseAPI; private ReleaseService releaseService;
@Mock @Mock
private AdminServiceAPI.ItemAPI itemAPI; private ItemService itemService;
@Mock @Mock
private PropertyResolver resolver; private PropertyResolver resolver;
@Mock @Mock
...@@ -82,9 +82,9 @@ public class NamespaceServiceTest { ...@@ -82,9 +82,9 @@ public class NamespaceServiceTest {
.thenReturn(applicationAppNamespace); .thenReturn(applicationAppNamespace);
when(appNamespaceService.findPublicAppNamespace("hermes")).thenReturn(hermesAppNamespace); when(appNamespaceService.findPublicAppNamespace("hermes")).thenReturn(hermesAppNamespace);
when(namespaceAPI.findNamespaceByCluster(appId, Env.DEV, clusterName)).thenReturn(namespaces); when(namespaceAPI.findNamespaceByCluster(appId, Env.DEV, clusterName)).thenReturn(namespaces);
when(releaseAPI.loadLatestRelease(appId, Env.DEV, clusterName, namespaceName)).thenReturn(someRelease); when(releaseService.loadLatestRelease(appId, Env.DEV, clusterName, namespaceName)).thenReturn(someRelease);
when(releaseAPI.loadLatestRelease(appId, Env.DEV, clusterName, "hermes")).thenReturn(someRelease); when(releaseService.loadLatestRelease(appId, Env.DEV, clusterName, "hermes")).thenReturn(someRelease);
when(itemAPI.findItems(appId, Env.DEV, clusterName, namespaceName)).thenReturn(someItems); when(itemService.findItems(appId, Env.DEV, clusterName, namespaceName)).thenReturn(someItems);
List<NamespaceVO> namespaceVOs = namespaceService.findNamespaces(appId, Env.DEV, clusterName); List<NamespaceVO> namespaceVOs = namespaceService.findNamespaces(appId, Env.DEV, clusterName);
assertEquals(2, namespaceVOs.size()); assertEquals(2, namespaceVOs.size());
......
...@@ -17,6 +17,7 @@ import org.mockito.Mock; ...@@ -17,6 +17,7 @@ import org.mockito.Mock;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anySet; import static org.mockito.Matchers.anySet;
import static org.mockito.Matchers.anySetOf;
import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
...@@ -46,7 +47,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest { ...@@ -46,7 +47,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest {
roleInitializationService.initAppRoles(mockApp()); roleInitializationService.initAppRoles(mockApp());
verify(rolePermissionService, times(1)).findRoleByRoleName(RoleUtils.buildAppMasterRoleName(APP_ID)); verify(rolePermissionService, times(1)).findRoleByRoleName(RoleUtils.buildAppMasterRoleName(APP_ID));
verify(rolePermissionService, times(0)).assignRoleToUsers(anyString(), anySet(), anyString()); verify(rolePermissionService, times(0)).assignRoleToUsers(anyString(), anySetOf(String.class), anyString());
} }
@Test @Test
...@@ -62,7 +63,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest { ...@@ -62,7 +63,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest {
verify(rolePermissionService, times(1)).assignRoleToUsers( verify(rolePermissionService, times(1)).assignRoleToUsers(
RoleUtils.buildAppMasterRoleName(APP_ID), Sets.newHashSet(CURRENT_USER), CURRENT_USER); RoleUtils.buildAppMasterRoleName(APP_ID), Sets.newHashSet(CURRENT_USER), CURRENT_USER);
verify(rolePermissionService, times(2)).createPermission(any()); verify(rolePermissionService, times(2)).createPermission(any());
verify(rolePermissionService, times(3)).createRoleWithPermissions(any(), anySet()); verify(rolePermissionService, times(3)).createRoleWithPermissions(any(), anySetOf(Long.class));
} }
@Test @Test
...@@ -80,7 +81,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest { ...@@ -80,7 +81,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest {
verify(rolePermissionService, times(2)).findRoleByRoleName(anyString()); verify(rolePermissionService, times(2)).findRoleByRoleName(anyString());
verify(rolePermissionService, times(0)).createPermission(any()); verify(rolePermissionService, times(0)).createPermission(any());
verify(rolePermissionService, times(0)).createRoleWithPermissions(any(), anySet()); verify(rolePermissionService, times(0)).createRoleWithPermissions(any(), anySetOf(Long.class));
} }
@Test @Test
...@@ -101,7 +102,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest { ...@@ -101,7 +102,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest {
verify(rolePermissionService, times(2)).findRoleByRoleName(anyString()); verify(rolePermissionService, times(2)).findRoleByRoleName(anyString());
verify(rolePermissionService, times(2)).createPermission(any()); verify(rolePermissionService, times(2)).createPermission(any());
verify(rolePermissionService, times(2)).createRoleWithPermissions(any(), anySet()); verify(rolePermissionService, times(2)).createRoleWithPermissions(any(), anySetOf(Long.class));
} }
@Test @Test
...@@ -122,7 +123,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest { ...@@ -122,7 +123,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest {
verify(rolePermissionService, times(2)).findRoleByRoleName(anyString()); verify(rolePermissionService, times(2)).findRoleByRoleName(anyString());
verify(rolePermissionService, times(1)).createPermission(any()); verify(rolePermissionService, times(1)).createPermission(any());
verify(rolePermissionService, times(1)).createRoleWithPermissions(any(), anySet()); verify(rolePermissionService, times(1)).createRoleWithPermissions(any(), anySetOf(Long.class));
} }
private App mockApp(){ private App mockApp(){
......
INSERT INTO `consumerrole` (`Id`, `ConsumerId`, `RoleId`, `DataChange_CreatedBy`, `DataChange_LastModifiedBy`)
VALUES (890, 1, 990, 'someOperator', 'someOperator');
INSERT INTO `consumerrole` (`Id`, `ConsumerId`, `RoleId`, `DataChange_CreatedBy`, `DataChange_LastModifiedBy`)
VALUES (891, 2, 990, 'someOperator', 'someOperator');
...@@ -179,7 +179,7 @@ ...@@ -179,7 +179,7 @@
<dependency> <dependency>
<groupId>com.ctrip.framework.apollo-sso</groupId> <groupId>com.ctrip.framework.apollo-sso</groupId>
<artifactId>apollo-sso-ctrip</artifactId> <artifactId>apollo-sso-ctrip</artifactId>
<version>1.0.0</version> <version>1.1.0</version>
</dependency> </dependency>
<!--third party --> <!--third party -->
<dependency> <dependency>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment