diff --git a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/ClusterUpdateController.java b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/ClusterUpdateController.java index 2758a485f..874e26c3e 100644 --- a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/ClusterUpdateController.java +++ b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/ClusterUpdateController.java @@ -7,12 +7,7 @@ import com.ctrip.xpipe.redis.checker.controller.result.RetMessage; import com.ctrip.xpipe.redis.console.config.ConsoleConfig; import com.ctrip.xpipe.redis.console.controller.AbstractConsoleController; -import com.ctrip.xpipe.redis.console.controller.api.data.meta.CheckFailException; -import com.ctrip.xpipe.redis.console.controller.api.data.meta.ClusterCreateInfo; -import com.ctrip.xpipe.redis.console.controller.api.data.meta.ClusterExchangeNameInfo; -import com.ctrip.xpipe.redis.console.controller.api.data.meta.ClusterRegionExchangeInfo; -import com.ctrip.xpipe.redis.console.controller.api.data.meta.DcDetailInfo; -import com.ctrip.xpipe.redis.console.controller.api.data.meta.RegionInfo; +import com.ctrip.xpipe.redis.console.controller.api.data.meta.*; import com.ctrip.xpipe.redis.console.dto.AzGroupDTO; import com.ctrip.xpipe.redis.console.dto.ClusterCreateDTO; import com.ctrip.xpipe.redis.console.dto.ClusterDTO; @@ -42,11 +37,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; @RestController @@ -173,6 +164,18 @@ public List getClusters(@RequestParam(required=false, default return transformFromInner(clusterCreateInfoList); } + @GetMapping(value = "/clusterWithShards") + public List getClusterShards(@RequestParam(required=false, defaultValue = "one_way", name = "type") String clusterType) throws CheckFailException { + logger.info("[clusterWithShards]clusterType-{}", clusterType); + if (!ClusterType.isTypeValidate(clusterType)) { + throw new CheckFailException("unknown cluster type " + clusterType); + } + + List clusterDTOList = clusterService.getClusterWithShards(clusterType); + List clusterInfos = clusterDTOList.stream().map(ClusterInfo::new).collect(Collectors.toList()); + return clusterInfos; + } + @PutMapping(value = "/cluster/exchangename") public RetMessage exchangeName(@RequestBody ClusterExchangeNameInfo exchangeNameInfo) { diff --git a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ClusterCreateInfo.java b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ClusterCreateInfo.java index 76a6ad9cb..a1620dd09 100644 --- a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ClusterCreateInfo.java +++ b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ClusterCreateInfo.java @@ -41,63 +41,6 @@ public class ClusterCreateInfo extends AbstractCreateInfo{ @JsonInclude(JsonInclude.Include.NON_EMPTY) private List regions = new LinkedList<>(); -// public static String innerGroupType2OuterGroupType(String groupType) { -// if(DcGroupType.isSameGroupType(groupType, DcGroupType.DR_MASTER)){ -// return "drMaster"; -// }else if(DcGroupType.isSameGroupType(groupType, DcGroupType.MASTER)) { -// return "master"; -// } -// return "drMaster"; -// } - -// public static DcGroupType outerGroupType2InnerGroupType(String groupType) { -// if(null == groupType || "drMaster".equals(groupType)){ -// return DcGroupType.DR_MASTER; -// }else if("master".equals(groupType)){ -// return DcGroupType.MASTER; -// } -// throw new IllegalArgumentException("unknown group type:"+groupType); -// } - -// public static ClusterCreateInfo fromClusterTbl(ClusterTbl clusterTbl, List clusterRelatedDc, -// Map> clusterId2DcClusterTblsMap) { -// ClusterCreateInfo clusterCreateInfo = new ClusterCreateInfo(); -// -// clusterCreateInfo.setClusterId(clusterTbl.getId()); -// clusterCreateInfo.setDesc(clusterTbl.getClusterDescription()); -// clusterCreateInfo.setClusterName(clusterTbl.getClusterName()); -// clusterCreateInfo.setClusterType(clusterTbl.getClusterType()); -// OrganizationTbl organizationTbl = clusterTbl.getOrganizationInfo(); -// clusterCreateInfo.setOrganizationId(organizationTbl != null ? organizationTbl.getOrgId() : 0L); -// clusterCreateInfo.setClusterAdminEmails(clusterTbl.getClusterAdminEmails()); -// -// Map dcId2DcNameMap = new HashMap<>(); -// clusterRelatedDc.forEach(dcTbl -> { -// dcId2DcNameMap.put(dcTbl.getId(), dcTbl.getDcName()); -// if (dcTbl.getId() == clusterTbl.getActivedcId()) { -// clusterCreateInfo.addFirstDc(dcTbl.getDcName()); -// } else { -// clusterCreateInfo.addDc(dcTbl.getDcName()); -// } -// }); -// -// List dcClusterTbls = clusterId2DcClusterTblsMap.get(clusterTbl.getId()); -// dcClusterTbls.forEach(dcClusterTbl -> { -// DcDetailInfo dcDetailInfo = new DcDetailInfo() -// .setDcId(dcId2DcNameMap.get(dcClusterTbl.getDcId())) -// .setDcGroupName(dcClusterTbl.getGroupName()) -// .setDcGroupType(innerGroupType2OuterGroupType(dcClusterTbl.getGroupType())); -// if (dcClusterTbl.getDcId() == clusterTbl.getActivedcId()) { -// clusterCreateInfo.addFirstDcDetail(dcDetailInfo); -// } else { -// clusterCreateInfo.addDcDetail(dcDetailInfo); -// } -// }); -// -// -// return clusterCreateInfo; -// } - public ClusterCreateInfo(){ } @@ -135,30 +78,6 @@ public ClusterCreateInfo(ClusterDTO clusterDTO) { }).collect(Collectors.toList()); } - // TODO:找DBA确认是否在使用dcDetails字段,若不使用,可不生成dcDetails信息 -// if (!CollectionUtils.isEmpty(this.regions)) { -// for (RegionInfo regionInfo : this.regions) { -// String regionClusterType = regionInfo.getClusterType(); -// if (ClusterType.isSameClusterType(regionClusterType, ClusterType.ONE_WAY)) { -// for (String az : regionInfo.getAzs()) { -// DcDetailInfo detailInfo = new DcDetailInfo(); -// detailInfo.setDcId(az); -// detailInfo.setDcGroupType(innerGroupType2OuterGroupType(DcGroupType.DR_MASTER.name())); -// this.dcDetails.add(detailInfo); -// } -// } else if (ClusterType.isSameClusterType(regionClusterType, ClusterType.SINGLE_DC)) { -// -// } -// if (regionInfo.get) -// } -// this.dcs.forEach(dc -> { -// DcDetailInfo dcDetailInfo = new DcDetailInfo(); -// dcDetailInfo.setDcId(dc); -// dcDetailInfo.setDcGroupName(); -// dcDetailInfo.setDcGroupType(); -// -// }); -// } } public Long getClusterId() { diff --git a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ClusterInfo.java b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ClusterInfo.java new file mode 100644 index 000000000..2c7cbc2c5 --- /dev/null +++ b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ClusterInfo.java @@ -0,0 +1,80 @@ +package com.ctrip.xpipe.redis.console.controller.api.data.meta; + +import com.ctrip.xpipe.redis.console.dto.ClusterDTO; + +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author lishanglin + * date 2023/11/22 + */ +public class ClusterInfo { + + private long id; + + private String clusterName; + + private String clusterType; + + private Set shards; + + public ClusterInfo() { + + } + + public ClusterInfo(ClusterDTO clusterDTO) { + this.id = clusterDTO.getClusterId(); + this.clusterName = clusterDTO.getClusterName(); + this.clusterType = clusterDTO.getClusterType(); + if (null != clusterDTO.getShards()) { + this.shards = clusterDTO.getShards().stream().map(ShardInfo::new).collect(Collectors.toSet()); + } + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getClusterName() { + return clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public String getClusterType() { + return clusterType; + } + + public void setClusterType(String clusterType) { + this.clusterType = clusterType; + } + + public Set getShards() { + return shards; + } + + public void setShards(Set shards) { + this.shards = shards; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ClusterInfo that = (ClusterInfo) o; + return id == that.id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ShardInfo.java b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ShardInfo.java new file mode 100644 index 000000000..c940fee62 --- /dev/null +++ b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/controller/api/data/meta/ShardInfo.java @@ -0,0 +1,54 @@ +package com.ctrip.xpipe.redis.console.controller.api.data.meta; + +import com.ctrip.xpipe.redis.console.dto.ShardDTO; + +import java.util.Objects; + +/** + * @author lishanglin + * date 2023/11/22 + */ +public class ShardInfo { + + private long id; + + private String shardName; + + public ShardInfo() { + + } + + public ShardInfo(ShardDTO shardDTO) { + this.id = shardDTO.getShardId(); + this.shardName = shardDTO.getShardName(); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getShardName() { + return shardName; + } + + public void setShardName(String shardName) { + this.shardName = shardName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ShardInfo shardInfo = (ShardInfo) o; + return id == shardInfo.id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/dto/ClusterDTO.java b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/dto/ClusterDTO.java index b716955d7..d923584ba 100644 --- a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/dto/ClusterDTO.java +++ b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/dto/ClusterDTO.java @@ -2,7 +2,9 @@ import com.ctrip.xpipe.redis.console.model.ClusterTbl; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class ClusterDTO { @@ -16,6 +18,7 @@ public class ClusterDTO { private String adminEmails; private List azs; private List azGroups; + private Set shards; public ClusterDTO() { } @@ -107,4 +110,35 @@ public List getAzGroups() { public void setAzGroups(List azGroups) { this.azGroups = azGroups; } + + public Set getShards() { + return shards; + } + + public ClusterDTO addShard(ShardDTO shard) { + if (null == this.shards) this.shards = new HashSet<>(); + this.shards.add(shard); + return this; + } + + public void setShards(Set shards) { + this.shards = shards; + } + + @Override + public String toString() { + return "ClusterDTO{" + + "clusterId=" + clusterId + + ", clusterName='" + clusterName + '\'' + + ", clusterType='" + clusterType + '\'' + + ", activeAz='" + activeAz + '\'' + + ", description='" + description + '\'' + + ", orgName='" + orgName + '\'' + + ", cmsOrgId=" + cmsOrgId + + ", adminEmails='" + adminEmails + '\'' + + ", azs=" + azs + + ", azGroups=" + azGroups + + ", shards=" + shards + + '}'; + } } diff --git a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/dto/ShardDTO.java b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/dto/ShardDTO.java new file mode 100644 index 000000000..3391fa9ee --- /dev/null +++ b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/dto/ShardDTO.java @@ -0,0 +1,68 @@ +package com.ctrip.xpipe.redis.console.dto; + +import com.ctrip.xpipe.redis.console.model.ShardTbl; +import com.ctrip.xpipe.redis.core.entity.ShardMeta; + +import java.util.Objects; + +/** + * @author lishanglin + * date 2023/11/22 + */ +public class ShardDTO { + + private Long shardId; + + private String shardName; + + public ShardDTO() { + + } + + public ShardDTO(ShardTbl shardTbl) { + this.shardId = shardTbl.getId(); + this.shardName = shardTbl.getShardName(); + } + + public ShardDTO(ShardMeta shardMeta) { + this.shardId = shardMeta.getDbId(); + this.shardName = shardMeta.getId(); + } + + public Long getShardId() { + return shardId; + } + + public void setShardId(Long shardId) { + this.shardId = shardId; + } + + public String getShardName() { + return shardName; + } + + public void setShardName(String shardName) { + this.shardName = shardName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ShardDTO shardDTO = (ShardDTO) o; + return shardId.equals(shardDTO.shardId); + } + + @Override + public int hashCode() { + return Objects.hash(shardId); + } + + @Override + public String toString() { + return "ShardDTO{" + + "shardId=" + shardId + + ", shardName='" + shardName + '\'' + + '}'; + } +} diff --git a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/resources/DefaultMetaCache.java b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/resources/DefaultMetaCache.java index 6125eb6d1..8fb389ab6 100644 --- a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/resources/DefaultMetaCache.java +++ b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/resources/DefaultMetaCache.java @@ -23,6 +23,7 @@ import com.ctrip.xpipe.utils.VisibleForTesting; import org.springframework.beans.factory.annotation.Autowired; +import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.*; import java.util.concurrent.Executors; @@ -70,6 +71,12 @@ public class DefaultMetaCache extends AbstractMetaCache implements MetaCache, Co private AtomicBoolean taskTrigger = new AtomicBoolean(false); + @PostConstruct + public void setup() { + taskTrigger.compareAndSet(false,true); + startLoadMeta(); + } + @Override public void isleader() { if (taskTrigger.compareAndSet(false, true)) { diff --git a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/service/ClusterService.java b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/service/ClusterService.java index d15760374..d99aa62a2 100644 --- a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/service/ClusterService.java +++ b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/service/ClusterService.java @@ -35,6 +35,7 @@ public interface ClusterService { Long getAllCount(); ClusterDTO getCluster(String clusterName); List getClusters(String clusterType); + List getClusterWithShards(String clusterType); ClusterTbl createCluster(ClusterModel clusterModel); void createSingleGroupCluster(SingleGroupClusterCreateDTO clusterCreateDTO); diff --git a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/service/impl/ClusterServiceImpl.java b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/service/impl/ClusterServiceImpl.java index e4004398d..c9af0d64e 100644 --- a/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/service/impl/ClusterServiceImpl.java +++ b/redis/redis-console/src/main/java/com/ctrip/xpipe/redis/console/service/impl/ClusterServiceImpl.java @@ -12,12 +12,7 @@ import com.ctrip.xpipe.redis.console.dao.DcClusterDao; import com.ctrip.xpipe.redis.console.dao.RouteDao; import com.ctrip.xpipe.redis.console.dao.ShardDao; -import com.ctrip.xpipe.redis.console.dto.AzGroupDTO; -import com.ctrip.xpipe.redis.console.dto.ClusterCreateDTO; -import com.ctrip.xpipe.redis.console.dto.ClusterDTO; -import com.ctrip.xpipe.redis.console.dto.ClusterUpdateDTO; -import com.ctrip.xpipe.redis.console.dto.MultiGroupClusterCreateDTO; -import com.ctrip.xpipe.redis.console.dto.SingleGroupClusterCreateDTO; +import com.ctrip.xpipe.redis.console.dto.*; import com.ctrip.xpipe.redis.console.entity.AzGroupClusterEntity; import com.ctrip.xpipe.redis.console.entity.ClusterEntity; import com.ctrip.xpipe.redis.console.entity.DcClusterEntity; @@ -63,6 +58,7 @@ import org.unidal.dal.jdbc.DalException; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -366,6 +362,34 @@ public List getClusters(String clusterType) { return clusters; } + public List getClusterWithShards(String clusterType) { + List clusters = getClusters(clusterType); + Map clusterMap = clusters.stream() + .collect(Collectors.toMap(ClusterDTO::getClusterId, Function.identity())); + clusters.forEach(cluster -> cluster.setShards(new HashSet<>())); + + XpipeMeta xpipeMeta = metaCache.getXpipeMeta(); + if (null == xpipeMeta) { + logger.info("[getClusterWithShards][cache not ready]"); + return clusters; + } + + for (DcMeta dcMeta: xpipeMeta.getDcs().values()) { + if (null == dcMeta.getClusters()) continue; + for (ClusterMeta clusterMeta: dcMeta.getClusters().values()) { + ClusterDTO clusterDTO = clusterMap.get(clusterMeta.getDbId()); + if (null == clusterDTO) continue; + if (null == clusterMeta.getShards()) continue; + for (ShardMeta shardMeta: clusterMeta.getShards().values()) { + ShardDTO shardDTO = new ShardDTO(shardMeta); + clusterDTO.addShard(shardDTO); + } + } + } + + return clusters; + } + @Override @Transactional @DalTransaction