Commit 77cd568c by Jason Song Committed by GitHub

Merge pull request #384 from lepdou/0818

add delete cluster and namespace rest api
parents 92a90e90 2fcabd36
...@@ -88,7 +88,11 @@ public class ItemController { ...@@ -88,7 +88,11 @@ public class ItemController {
Item beforeUpdateItem = BeanUtils.transfrom(Item.class, managedEntity); Item beforeUpdateItem = BeanUtils.transfrom(Item.class, managedEntity);
BeanUtils.copyEntityProperties(entity, managedEntity); //protect. only value,comment,lastModifiedBy can be modified
managedEntity.setValue(entity.getValue());
managedEntity.setComment(entity.getComment());
managedEntity.setDataChangeLastModifiedBy(entity.getDataChangeLastModifiedBy());
entity = itemService.update(managedEntity); entity = itemService.update(managedEntity);
builder.updateItem(beforeUpdateItem, entity); builder.updateItem(beforeUpdateItem, entity);
itemDTO = BeanUtils.transfrom(ItemDTO.class, entity); itemDTO = BeanUtils.transfrom(ItemDTO.class, entity);
......
...@@ -49,7 +49,8 @@ public class NamespaceController { ...@@ -49,7 +49,8 @@ public class NamespaceController {
Namespace entity = namespaceService.findOne(appId, clusterName, namespaceName); Namespace entity = namespaceService.findOne(appId, clusterName, namespaceName);
if (entity == null) throw new NotFoundException( if (entity == null) throw new NotFoundException(
String.format("namespace not found for %s %s %s", appId, clusterName, namespaceName)); String.format("namespace not found for %s %s %s", appId, clusterName, namespaceName));
namespaceService.delete(entity.getId(), operator);
namespaceService.deleteNamespace(entity, operator);
} }
@RequestMapping("/apps/{appId}/clusters/{clusterName}/namespaces") @RequestMapping("/apps/{appId}/clusters/{clusterName}/namespaces")
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
<property name="LOG_FILE" <property name="LOG_FILE"
value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}apollo-assembly.log}" /> value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}apollo-assembly.log}" />
<include resource="org/springframework/boot/logging/logback/file-appender.xml" /> <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<root level="INFO"> <root level="INFO">
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root> </root>
</configuration> </configuration>
...@@ -10,8 +10,8 @@ import javax.persistence.Entity; ...@@ -10,8 +10,8 @@ import javax.persistence.Entity;
import javax.persistence.Table; import javax.persistence.Table;
@Entity @Entity
@Table(name = "commit") @Table(name = "Commit")
@SQLDelete(sql = "Update commit set isDeleted = 1 where id = ?") @SQLDelete(sql = "Update Commit set isDeleted = 1 where id = ?")
@Where(clause = "isDeleted = 0") @Where(clause = "isDeleted = 0")
public class Commit extends BaseEntity { public class Commit extends BaseEntity {
......
...@@ -3,6 +3,8 @@ package com.ctrip.framework.apollo.biz.repository; ...@@ -3,6 +3,8 @@ package com.ctrip.framework.apollo.biz.repository;
import com.ctrip.framework.apollo.biz.entity.Commit; import com.ctrip.framework.apollo.biz.entity.Commit;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List; import java.util.List;
...@@ -10,6 +12,10 @@ import java.util.List; ...@@ -10,6 +12,10 @@ import java.util.List;
public interface CommitRepository extends PagingAndSortingRepository<Commit, Long> { public interface CommitRepository extends PagingAndSortingRepository<Commit, Long> {
List<Commit> findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(String appId, String clusterName, List<Commit> findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(String appId, String clusterName,
String namespaceName, Pageable pageable); String namespaceName, Pageable pageable);
@Modifying
@Query("update Commit set isdeleted=1,DataChange_LastModifiedBy = ?4 where appId=?1 and clusterName=?2 and namespaceName = ?3")
int batchDelete(String appId, String clusterName, String namespaceName, String operator);
} }
...@@ -2,6 +2,8 @@ package com.ctrip.framework.apollo.biz.repository; ...@@ -2,6 +2,8 @@ package com.ctrip.framework.apollo.biz.repository;
import java.util.List; import java.util.List;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import com.ctrip.framework.apollo.biz.entity.Item; import com.ctrip.framework.apollo.biz.entity.Item;
...@@ -14,4 +16,8 @@ public interface ItemRepository extends PagingAndSortingRepository<Item, Long> { ...@@ -14,4 +16,8 @@ public interface ItemRepository extends PagingAndSortingRepository<Item, Long> {
Item findFirst1ByNamespaceIdOrderByLineNumDesc(Long namespaceId); Item findFirst1ByNamespaceIdOrderByLineNumDesc(Long namespaceId);
@Modifying
@Query("update Item set isdeleted=1,DataChange_LastModifiedBy = ?2 where namespaceId = ?1")
int deleteByNamespaceId(long namespaceId, String operator);
} }
...@@ -2,6 +2,8 @@ package com.ctrip.framework.apollo.biz.repository; ...@@ -2,6 +2,8 @@ package com.ctrip.framework.apollo.biz.repository;
import java.util.List; import java.util.List;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import com.ctrip.framework.apollo.biz.entity.Namespace; import com.ctrip.framework.apollo.biz.entity.Namespace;
...@@ -11,4 +13,9 @@ public interface NamespaceRepository extends PagingAndSortingRepository<Namespac ...@@ -11,4 +13,9 @@ public interface NamespaceRepository extends PagingAndSortingRepository<Namespac
List<Namespace> findByAppIdAndClusterNameOrderByIdAsc(String appId, String clusterName); List<Namespace> findByAppIdAndClusterNameOrderByIdAsc(String appId, String clusterName);
Namespace findByAppIdAndClusterNameAndNamespaceName(String appId, String clusterName, String namespaceName); Namespace findByAppIdAndClusterNameAndNamespaceName(String appId, String clusterName, String namespaceName);
@Modifying
@Query("update Namespace set isdeleted=1,DataChange_LastModifiedBy = ?3 where appId=?1 and clusterName=?2")
int batchDelete(String appId, String clusterName, String operator);
} }
...@@ -3,6 +3,8 @@ package com.ctrip.framework.apollo.biz.repository; ...@@ -3,6 +3,8 @@ package com.ctrip.framework.apollo.biz.repository;
import java.util.List; import java.util.List;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
...@@ -19,4 +21,8 @@ public interface ReleaseRepository extends PagingAndSortingRepository<Release, L ...@@ -19,4 +21,8 @@ public interface ReleaseRepository extends PagingAndSortingRepository<Release, L
List<Release> findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(String appId, String clusterName, String namespaceName, Pageable page); List<Release> findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(String appId, String clusterName, String namespaceName, Pageable page);
List<Release> findByAppIdAndClusterNameAndNamespaceNameAndIsAbandonedFalseOrderByIdDesc(String appId, String clusterName, String namespaceName, Pageable page); List<Release> findByAppIdAndClusterNameAndNamespaceNameAndIsAbandonedFalseOrderByIdDesc(String appId, String clusterName, String namespaceName, Pageable page);
@Modifying
@Query("update Release set isdeleted=1,DataChange_LastModifiedBy = ?4 where appId=?1 and clusterName=?2 and namespaceName = ?3")
int batchDelete(String appId, String clusterName, String namespaceName, String operator);
} }
...@@ -11,6 +11,7 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -11,6 +11,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.ctrip.framework.apollo.biz.entity.Audit; import com.ctrip.framework.apollo.biz.entity.Audit;
import com.ctrip.framework.apollo.biz.entity.Cluster; import com.ctrip.framework.apollo.biz.entity.Cluster;
import com.ctrip.framework.apollo.biz.repository.ClusterRepository; import com.ctrip.framework.apollo.biz.repository.ClusterRepository;
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.core.ConfigConsts; import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.common.exception.ServiceException; import com.ctrip.framework.apollo.common.exception.ServiceException;
...@@ -26,8 +27,6 @@ public class ClusterService { ...@@ -26,8 +27,6 @@ public class ClusterService {
private AuditService auditService; private AuditService auditService;
@Autowired @Autowired
private NamespaceService namespaceService; private NamespaceService namespaceService;
@Autowired
private AppNamespaceService appNamespaceService;
public boolean isClusterNameUnique(String appId, String clusterName) { public boolean isClusterNameUnique(String appId, String clusterName) {
...@@ -75,9 +74,12 @@ public class ClusterService { ...@@ -75,9 +74,12 @@ public class ClusterService {
public void delete(long id, String operator) { public void delete(long id, String operator) {
Cluster cluster = clusterRepository.findOne(id); Cluster cluster = clusterRepository.findOne(id);
if (cluster == null) { if (cluster == null) {
return; throw new BadRequestException("cluster not exist");
} }
//delete linked namespaces
namespaceService.deleteByAppIdAndClusterName(cluster.getAppId(), cluster.getName(), operator);
cluster.setDeleted(true); cluster.setDeleted(true);
cluster.setDataChangeLastModifiedBy(operator); cluster.setDataChangeLastModifiedBy(operator);
clusterRepository.save(cluster); clusterRepository.save(cluster);
......
...@@ -26,4 +26,9 @@ public class CommitService { ...@@ -26,4 +26,9 @@ public class CommitService {
return commitRepository.findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(appId, clusterName, namespaceName, page); return commitRepository.findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(appId, clusterName, namespaceName, page);
} }
@Transactional
public int batchDelete(String appId, String clusterName, String namespaceName, String operator){
return commitRepository.batchDelete(appId, clusterName, namespaceName, operator);
}
} }
...@@ -47,6 +47,12 @@ public class ItemService { ...@@ -47,6 +47,12 @@ public class ItemService {
return deletedItem; return deletedItem;
} }
@Transactional
public int batchDelete(long namespaceId, String operator) {
return itemRepository.deleteByNamespaceId(namespaceId, operator);
}
public Item findOne(String appId, String clusterName, String namespaceName, String key) { public Item findOne(String appId, String clusterName, String namespaceName, String key) {
Namespace namespace = namespaceRepository.findByAppIdAndClusterNameAndNamespaceName(appId, Namespace namespace = namespaceRepository.findByAppIdAndClusterNameAndNamespaceName(appId,
clusterName, namespaceName); clusterName, namespaceName);
......
...@@ -13,7 +13,6 @@ import com.ctrip.framework.apollo.common.utils.BeanUtils; ...@@ -13,7 +13,6 @@ import com.ctrip.framework.apollo.common.utils.BeanUtils;
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.exception.NotFoundException; import com.ctrip.framework.apollo.common.exception.NotFoundException;
import com.ctrip.framework.apollo.core.utils.StringUtils;
@Service @Service
...@@ -50,14 +49,19 @@ public class ItemSetService { ...@@ -50,14 +49,19 @@ public class ItemSetService {
for (ItemDTO item : changeSet.getUpdateItems()) { for (ItemDTO item : changeSet.getUpdateItems()) {
Item entity = BeanUtils.transfrom(Item.class, item); Item entity = BeanUtils.transfrom(Item.class, item);
Item beforeUpdateItem = itemService.findOne(entity.getId()); Item managedItem = itemService.findOne(entity.getId());
if (beforeUpdateItem == null) { if (managedItem == null) {
throw new NotFoundException(String.format("item not found.(key=%s)", entity.getKey())); throw new NotFoundException(String.format("item not found.(key=%s)", entity.getKey()));
} }
beforeUpdateItem = BeanUtils.transfrom(Item.class, beforeUpdateItem); Item beforeUpdateItem = BeanUtils.transfrom(Item.class, managedItem);
//protect. only value,comment,lastModifiedBy,lineNum can be modified
managedItem.setValue(entity.getValue());
managedItem.setComment(entity.getComment());
managedItem.setLineNum(entity.getLineNum());
entity.setDataChangeLastModifiedBy(operator); entity.setDataChangeLastModifiedBy(operator);
Item updatedItem = itemService.update(entity);
Item updatedItem = itemService.update(managedItem);
configChangeContentBuilder.updateItem(beforeUpdateItem, updatedItem); configChangeContentBuilder.updateItem(beforeUpdateItem, updatedItem);
} }
...@@ -72,8 +76,7 @@ public class ItemSetService { ...@@ -72,8 +76,7 @@ public class ItemSetService {
auditService.audit("ItemSet", null, Audit.OP.DELETE, operator); auditService.audit("ItemSet", null, Audit.OP.DELETE, operator);
} }
String configChangeContent = configChangeContentBuilder.build(); if (configChangeContentBuilder.hasContent()){
if (!StringUtils.isEmpty(configChangeContent)) {
createCommit(appId, clusterName, namespaceName, configChangeContentBuilder.build(), createCommit(appId, clusterName, namespaceName, configChangeContentBuilder.build(),
changeSet.getDataChangeLastModifiedBy()); changeSet.getDataChangeLastModifiedBy());
} }
......
...@@ -24,6 +24,13 @@ public class NamespaceService { ...@@ -24,6 +24,13 @@ public class NamespaceService {
private AuditService auditService; private AuditService auditService;
@Autowired @Autowired
private AppNamespaceService appNamespaceService; private AppNamespaceService appNamespaceService;
@Autowired
private ItemService itemService;
@Autowired
private CommitService commitService;
@Autowired
private ReleaseService releaseService;
public boolean isNamespaceUnique(String appId, String cluster, String namespace) { public boolean isNamespaceUnique(String appId, String cluster, String namespace) {
Objects.requireNonNull(appId, "AppId must not be null"); Objects.requireNonNull(appId, "AppId must not be null");
...@@ -34,17 +41,32 @@ public class NamespaceService { ...@@ -34,17 +41,32 @@ public class NamespaceService {
} }
@Transactional @Transactional
public void delete(long id, String operator) { public void deleteByAppIdAndClusterName(String appId, String clusterName, String operator){
Namespace namespace = namespaceRepository.findOne(id);
if (namespace == null) { List<Namespace> toDeleteNamespaces = findNamespaces(appId, clusterName);
return;
for (Namespace namespace: toDeleteNamespaces){
deleteNamespace(namespace, operator);
} }
}
@Transactional
public Namespace deleteNamespace(Namespace namespace, String operator){
String appId = namespace.getAppId();
String clusterName = namespace.getClusterName();
itemService.batchDelete(namespace.getId(), operator);
commitService.batchDelete(appId, clusterName, namespace.getNamespaceName(), operator);
releaseService.batchDelete(appId, clusterName, namespace.getNamespaceName(), operator);
namespace.setDeleted(true); namespace.setDeleted(true);
namespace.setDataChangeLastModifiedBy(operator); namespace.setDataChangeLastModifiedBy(operator);
namespaceRepository.save(namespace);
auditService.audit(Namespace.class.getSimpleName(), id, Audit.OP.DELETE, operator); auditService.audit(Namespace.class.getSimpleName(), namespace.getId(), Audit.OP.DELETE, operator);
return namespaceRepository.save(namespace);
} }
public Namespace findOne(Long namespaceId) { public Namespace findOne(Long namespaceId) {
......
...@@ -142,4 +142,9 @@ public class ReleaseService { ...@@ -142,4 +142,9 @@ public class ReleaseService {
return releaseRepository.save(release); return releaseRepository.save(release);
} }
@Transactional
public int batchDelete(String appId, String clusterName, String namespaceName, String operator){
return releaseRepository.batchDelete(appId, clusterName, namespaceName, operator);
}
} }
...@@ -4,7 +4,9 @@ import com.google.gson.Gson; ...@@ -4,7 +4,9 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.ctrip.framework.apollo.biz.entity.Item; import com.ctrip.framework.apollo.biz.entity.Item;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
...@@ -20,7 +22,9 @@ public class ConfigChangeContentBuilder { ...@@ -20,7 +22,9 @@ public class ConfigChangeContentBuilder {
public ConfigChangeContentBuilder createItem(Item item) { public ConfigChangeContentBuilder createItem(Item item) {
createItems.add(item); if (!StringUtils.isEmpty(item.getKey())){
createItems.add(item);
}
return this; return this;
} }
...@@ -33,10 +37,16 @@ public class ConfigChangeContentBuilder { ...@@ -33,10 +37,16 @@ public class ConfigChangeContentBuilder {
} }
public ConfigChangeContentBuilder deleteItem(Item item) { public ConfigChangeContentBuilder deleteItem(Item item) {
deleteItems.add(item); if (!StringUtils.isEmpty(item.getKey())) {
deleteItems.add(item);
}
return this; return this;
} }
public boolean hasContent(){
return !createItems.isEmpty() || !updateItems.isEmpty() || !deleteItems.isEmpty();
}
public String build() { public String build() {
//因为事务第一段提交并没有更新时间,所以build时统一更新 //因为事务第一段提交并没有更新时间,所以build时统一更新
for (Item item : createItems) { for (Item item : createItems) {
......
...@@ -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) {
...@@ -78,6 +78,11 @@ public class AdminServiceAPI { ...@@ -78,6 +78,11 @@ public class AdminServiceAPI {
.post(env, "apps/{appId}/appnamespaces", appNamespace, AppNamespaceDTO.class, appNamespace.getAppId()); .post(env, "apps/{appId}/appnamespaces", appNamespace, AppNamespaceDTO.class, appNamespace.getAppId());
} }
public void deleteNamespace(Env env, String appId, String clusterName, String namespaceName, String operator) {
restTemplate.delete(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}?operator={operator}", appId, clusterName,
namespaceName, operator);
}
} }
@Service @Service
...@@ -86,7 +91,7 @@ public class AdminServiceAPI { ...@@ -86,7 +91,7 @@ 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);
} }
...@@ -98,18 +103,18 @@ public class AdminServiceAPI { ...@@ -98,18 +103,18 @@ public class AdminServiceAPI {
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) {
...@@ -123,25 +128,29 @@ public class AdminServiceAPI { ...@@ -123,25 +128,29 @@ 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());
}
public void delete(Env env, String appId, String clusterName, String operator) {
restTemplate.delete(env, "apps/{appId}/clusters/{clusterName}?operator={operator}", appId, clusterName, operator);
} }
} }
...@@ -175,7 +184,7 @@ public class AdminServiceAPI { ...@@ -175,7 +184,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;
} }
...@@ -198,8 +207,8 @@ public class AdminServiceAPI { ...@@ -198,8 +207,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);
} }
} }
...@@ -209,9 +218,9 @@ public class AdminServiceAPI { ...@@ -209,9 +218,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);
} }
...@@ -222,8 +231,8 @@ public class AdminServiceAPI { ...@@ -222,8 +231,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);
} }
} }
......
...@@ -9,6 +9,7 @@ import com.ctrip.framework.apollo.portal.auth.UserInfoHolder; ...@@ -9,6 +9,7 @@ import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.service.ClusterService; import com.ctrip.framework.apollo.portal.service.ClusterService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
...@@ -45,4 +46,13 @@ public class ClusterController { ...@@ -45,4 +46,13 @@ public class ClusterController {
return clusterService.createCluster(Env.valueOf(env), cluster); return clusterService.createCluster(Env.valueOf(env), cluster);
} }
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@RequestMapping(value = "apps/{appId}/envs/{env}/clusters/{clusterName:.+}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deleteCluster(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName){
clusterService.deleteCluster(Env.valueOf(env), appId, clusterName);
return ResponseEntity.ok().build();
}
} }
...@@ -43,7 +43,6 @@ public class NamespaceController { ...@@ -43,7 +43,6 @@ public class NamespaceController {
@Autowired @Autowired
private AppService appService; private AppService appService;
@Autowired @Autowired
private ApplicationEventPublisher publisher; private ApplicationEventPublisher publisher;
@Autowired @Autowired
...@@ -86,6 +85,14 @@ public class NamespaceController { ...@@ -86,6 +85,14 @@ public class NamespaceController {
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName:.+}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deleteNamespace(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName){
namespaceService.deleteNamespace(appId, Env.valueOf(env), clusterName, namespaceName);
return ResponseEntity.ok().build();
}
@PreAuthorize(value = "@permissionValidator.hasCreateAppNamespacePermission(#appId, #appNamespace)") @PreAuthorize(value = "@permissionValidator.hasCreateAppNamespacePermission(#appId, #appNamespace)")
@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) {
......
...@@ -4,6 +4,7 @@ import com.ctrip.framework.apollo.common.dto.ClusterDTO; ...@@ -4,6 +4,7 @@ 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.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.auth.UserInfoHolder;
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;
...@@ -16,6 +17,8 @@ import java.util.List; ...@@ -16,6 +17,8 @@ import java.util.List;
public class ClusterService { public class ClusterService {
@Autowired @Autowired
private UserInfoHolder userInfoHolder;
@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) {
...@@ -33,4 +36,8 @@ public class ClusterService { ...@@ -33,4 +36,8 @@ public class ClusterService {
return clusterDTO; return clusterDTO;
} }
public void deleteCluster(Env env, String appId, String clusterName){
clusterAPI.delete(env, appId, clusterName, userInfoHolder.getUser().getUserId());
}
} }
package com.ctrip.framework.apollo.portal.service; package com.ctrip.framework.apollo.portal.service;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
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;
...@@ -22,6 +23,7 @@ import org.slf4j.LoggerFactory; ...@@ -22,6 +23,7 @@ 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.lang.reflect.Type;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
...@@ -32,6 +34,8 @@ public class NamespaceService { ...@@ -32,6 +34,8 @@ public class NamespaceService {
private Logger logger = LoggerFactory.getLogger(NamespaceService.class); private Logger logger = LoggerFactory.getLogger(NamespaceService.class);
private Gson gson = new Gson(); private Gson gson = new Gson();
private static Type mapType = new TypeToken<Map<String, String>>() {
}.getType();
@Autowired @Autowired
private UserInfoHolder userInfoHolder; private UserInfoHolder userInfoHolder;
...@@ -58,6 +62,10 @@ public class NamespaceService { ...@@ -58,6 +62,10 @@ public class NamespaceService {
return createdNamespace; return createdNamespace;
} }
public void deleteNamespace(String appId, Env env, String clusterName, String namespaceName){
namespaceAPI.deleteNamespace(env, appId, clusterName, namespaceName, userInfoHolder.getUser().getUserId());
}
public NamespaceDTO loadNamespaceBaseInfo(String appId, Env env, String clusterName, String namespaceName) { public NamespaceDTO loadNamespaceBaseInfo(String appId, Env env, String clusterName, String namespaceName) {
NamespaceDTO namespace = namespaceAPI.loadNamespace(appId, env, clusterName, namespaceName); NamespaceDTO namespace = namespaceAPI.loadNamespace(appId, env, clusterName, namespaceName);
if (namespace == null) { if (namespace == null) {
...@@ -101,7 +109,6 @@ public class NamespaceService { ...@@ -101,7 +109,6 @@ public class NamespaceService {
return parseNamespace(appId, env, clusterName, namespace); return parseNamespace(appId, env, clusterName, namespace);
} }
@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();
namespaceVO.setBaseInfo(namespace); namespaceVO.setBaseInfo(namespace);
...@@ -118,7 +125,7 @@ public class NamespaceService { ...@@ -118,7 +125,7 @@ public class NamespaceService {
Map<String, String> releaseItems = new HashMap<>(); Map<String, String> releaseItems = new HashMap<>();
latestRelease = releaseService.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(), mapType);
} }
//not Release config items //not Release config items
......
...@@ -24,9 +24,6 @@ ...@@ -24,9 +24,6 @@
</header> </header>
<div class="panel-body"> <div class="panel-body">
<div class="alert alert-info" role="alert">
apollo系统目前正在框架部门内测阶段,如非框架项目接入请先联系song_s@ctrip.com,zhanglea@ctrip.com
</div>
<form class="form-horizontal" name="appForm" ng-controller="CreateAppController" valdr-type="App" <form class="form-horizontal" name="appForm" ng-controller="CreateAppController" valdr-type="App"
ng-submit="create()"> ng-submit="create()">
<div class="form-group"> <div class="form-group">
......
...@@ -17,6 +17,7 @@ $(document).ready(function () { ...@@ -17,6 +17,7 @@ $(document).ready(function () {
$('[data-tooltip="tooltip"]').tooltip(); $('[data-tooltip="tooltip"]').tooltip();
$("textarea").niceScroll({styler: "fb", cursorcolor: "#fff"}); $("textarea").niceScroll({styler: "fb", cursorcolor: "#fff"});
$("pre").niceScroll({styler: "fb", cursorcolor: "#fff"});
}, 2500); }, 2500);
}); });
......
...@@ -13,7 +13,6 @@ application_module.controller("ConfigNamespaceController", ...@@ -13,7 +13,6 @@ application_module.controller("ConfigNamespaceController",
}; };
var TABLE_VIEW_OPER_TYPE = { var TABLE_VIEW_OPER_TYPE = {
RETRIEVE: 'retrieve',
CREATE: 'create', CREATE: 'create',
UPDATE: 'update' UPDATE: 'update'
}; };
...@@ -25,6 +24,8 @@ application_module.controller("ConfigNamespaceController", ...@@ -25,6 +24,8 @@ application_module.controller("ConfigNamespaceController",
$scope.prepareReleaseNamespace = prepareReleaseNamespace; $scope.prepareReleaseNamespace = prepareReleaseNamespace;
$scope.release = release; $scope.release = release;
$scope.switchReleaseChangeViewType = switchReleaseChangeViewType;
$scope.showRollbackAlertDialog = showRollbackAlertDialog; $scope.showRollbackAlertDialog = showRollbackAlertDialog;
...@@ -32,13 +33,13 @@ application_module.controller("ConfigNamespaceController", ...@@ -32,13 +33,13 @@ application_module.controller("ConfigNamespaceController",
$scope.rollback = rollback; $scope.rollback = rollback;
$scope.retrieveItem = retrieveItem;
$scope.preDeleteItem = preDeleteItem; $scope.preDeleteItem = preDeleteItem;
$scope.deleteItem = deleteItem; $scope.deleteItem = deleteItem;
$scope.editItem = editItem; $scope.editItem = editItem;
$scope.cancelEdit = cancelEdit;
$scope.createItem = createItem; $scope.createItem = createItem;
...@@ -152,6 +153,11 @@ application_module.controller("ConfigNamespaceController", ...@@ -152,6 +153,11 @@ application_module.controller("ConfigNamespaceController",
} }
); );
} }
$scope.releaseChangeViewType = 'change';
function switchReleaseChangeViewType(type) {
$scope.releaseChangeViewType = type;
}
function showRollbackAlertDialog() { function showRollbackAlertDialog() {
$("#rollbackModal").modal('hide'); $("#rollbackModal").modal('hide');
...@@ -209,15 +215,6 @@ application_module.controller("ConfigNamespaceController", ...@@ -209,15 +215,6 @@ application_module.controller("ConfigNamespaceController",
$scope.tableViewOperType = '', $scope.item = {}; $scope.tableViewOperType = '', $scope.item = {};
var toOperationNamespace; var toOperationNamespace;
//查看配置
function retrieveItem(namespace, item, oldValue) {
switchTableViewOperType(TABLE_VIEW_OPER_TYPE.RETRIEVE);
$scope.item = item;
$scope.item.oldValue = oldValue;
toOperationNamespace = namespace;
$scope.hasModifyPermission = namespace.hasModifyPermission;
}
var toDeleteItemId = 0; var toDeleteItemId = 0;
function preDeleteItem(namespace, itemId) { function preDeleteItem(namespace, itemId) {
...@@ -245,6 +242,7 @@ application_module.controller("ConfigNamespaceController", ...@@ -245,6 +242,7 @@ application_module.controller("ConfigNamespaceController",
}); });
} }
var backupItem = {};
//修改配置 //修改配置
function editItem(namespace, item) { function editItem(namespace, item) {
if (!lockCheck(namespace)) { if (!lockCheck(namespace)) {
...@@ -252,10 +250,19 @@ application_module.controller("ConfigNamespaceController", ...@@ -252,10 +250,19 @@ application_module.controller("ConfigNamespaceController",
} }
switchTableViewOperType(TABLE_VIEW_OPER_TYPE.UPDATE); switchTableViewOperType(TABLE_VIEW_OPER_TYPE.UPDATE);
$scope.item = item; $scope.item = item;
backupItem.value = item.value;
backupItem.comment = item.comment;
toOperationNamespace = namespace; toOperationNamespace = namespace;
$("#itemModal").modal("show"); $("#itemModal").modal("show");
} }
function cancelEdit() {
if($scope.tableViewOperType = TABLE_VIEW_OPER_TYPE.UPDATE){
$scope.item.value = backupItem.value;
$scope.item.comment = backupItem.comment;
}
}
//新增配置 //新增配置
function createItem(namespace) { function createItem(namespace) {
......
directive_module.directive('apollodiff',
function ($compile, $window) {
return {
restrict: 'E',
templateUrl: '../../views/component/diff.html',
transclude: true,
replace: true,
scope: {
oldStr: '=',
newStr: '=',
apolloId: '='
},
link: function (scope, element, attrs) {
scope.$watch('oldStr', makeDiff);
scope.$watch('newStr', makeDiff);
function makeDiff() {
var displayArea = document.getElementById(scope.apolloId);
if (!displayArea){
return;
}
//clear
displayArea.innerHTML = '';
var color = '',
span = null,
pre = '';
var diff = JsDiff.diffLines(scope.oldStr, scope.newStr),
fragment = document.createDocumentFragment();
diff.forEach(function (part) {
// green for additions, red for deletions
// grey for common parts
color = part.added ? 'green' :
part.removed ? 'red' : 'grey';
span = document.createElement('span');
span.style.color = color;
pre = part.added ? '+' :
part.removed ? '-' : '';
span.appendChild(document.createTextNode(pre + part.value));
fragment.appendChild(span);
});
displayArea.appendChild(fragment);
}
}
}
});
...@@ -232,8 +232,8 @@ ...@@ -232,8 +232,8 @@
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="item in commits.changeSets.createItems" <!--兼容老数据,不显示item类型为空行和注释的item-->
ng-show="item.key || item.comment"> <tr ng-repeat="item in commits.changeSets.createItems" ng-show="item.key">
<td width="2%"> <td width="2%">
新增 新增
</td> </td>
......
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