You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2023/03/23 02:07:32 UTC

[dubbo-admin] branch refactor-with-go updated: feat: refactor the condition route feature with go (#1052)

This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch refactor-with-go
in repository https://gitbox.apache.org/repos/asf/dubbo-admin.git


The following commit(s) were added to refs/heads/refactor-with-go by this push:
     new 5ed5b9be feat: refactor the condition route feature with go (#1052)
5ed5b9be is described below

commit 5ed5b9be9ab83f1ca5aa7bcccb8580c8523ce29a
Author: Yixiang Zhao <se...@foxmail.com>
AuthorDate: Thu Mar 23 10:07:27 2023 +0800

    feat: refactor the condition route feature with go (#1052)
---
 pkg/admin/constant/const.go                        |   1 +
 .../handlers/{tag_route.go => condition_route.go}  |  78 +++---
 pkg/admin/handlers/tag_route.go                    |  18 +-
 .../condition_route.go}                            |  29 ++-
 pkg/admin/router/router.go                         |  11 +
 .../{tag_route_service.go => route_service.go}     |  10 +-
 pkg/admin/services/route_service_impl.go           | 268 +++++++++++++++++++++
 pkg/admin/services/tag_route_service_impl.go       | 125 ----------
 8 files changed, 359 insertions(+), 181 deletions(-)

diff --git a/pkg/admin/constant/const.go b/pkg/admin/constant/const.go
index bc0c15a9..f5f4995a 100644
--- a/pkg/admin/constant/const.go
+++ b/pkg/admin/constant/const.go
@@ -59,6 +59,7 @@ const (
 	BalancingKey           = "balancing"
 	DefaultWeight          = 100
 	OwnerKey               = "owner"
+	Application            = "application"
 	Service                = "service"
 	Colon                  = ":"
 	InterrogationPoint     = "?"
diff --git a/pkg/admin/handlers/tag_route.go b/pkg/admin/handlers/condition_route.go
similarity index 62%
copy from pkg/admin/handlers/tag_route.go
copy to pkg/admin/handlers/condition_route.go
index baa17d06..24fda507 100644
--- a/pkg/admin/handlers/tag_route.go
+++ b/pkg/admin/handlers/condition_route.go
@@ -19,26 +19,19 @@ package handlers
 
 import (
 	"net/http"
-	"strings"
 
-	"github.com/apache/dubbo-admin/pkg/admin/config"
 	"github.com/apache/dubbo-admin/pkg/admin/model"
-	"github.com/apache/dubbo-admin/pkg/admin/services"
 	"github.com/gin-gonic/gin"
 )
 
-var tagRouteService services.TagRoutesService = &services.TagRoutesServiceImpl{
-	GovernanceConfig: &config.GovernanceConfigImpl{},
-}
-
-func CreateRule(c *gin.Context) {
-	var tagRouteDto model.TagRouteDto
-	err := c.BindJSON(&tagRouteDto)
+func CreateConditionRule(c *gin.Context) {
+	var routeDto model.ConditionRouteDto
+	err := c.BindJSON(&routeDto)
 	if err != nil {
 		panic(err)
 	}
 
-	err = tagRouteService.CreateTagRoute(tagRouteDto)
+	err = routeService.CreateConditionRoute(routeDto)
 
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
@@ -52,16 +45,15 @@ func CreateRule(c *gin.Context) {
 	})
 }
 
-func UpdateRule(c *gin.Context) {
-	var tagRouteDto model.TagRouteDto
-	err := c.BindJSON(&tagRouteDto)
+func UpdateConditionRule(c *gin.Context) {
+	var routeDto model.ConditionRouteDto
+	err := c.BindJSON(&routeDto)
 	if err != nil {
 		panic(err)
 	}
 	id := c.Param("id")
-	id = strings.ReplaceAll(id, "*", "/")
 
-	_, err = tagRouteService.FindTagRoute(id)
+	_, err = routeService.FindConditionRouteById(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -69,7 +61,7 @@ func UpdateRule(c *gin.Context) {
 		return
 	}
 
-	err = tagRouteService.UpdateTagRoute(tagRouteDto)
+	err = routeService.UpdateConditionRoute(routeDto)
 
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
@@ -83,10 +75,30 @@ func UpdateRule(c *gin.Context) {
 	})
 }
 
-func SearchRoutes(c *gin.Context) {
+func SearchConditionRoutes(c *gin.Context) {
 	application := c.Query("application")
+	service := c.Query("service")
+	serviceVersion := c.Query("serviceVersion")
+	serviceGroup := c.Query("serviceGroup")
+
+	var routeDto model.ConditionRouteDto
+	var err error
+	crDto := model.ConditionRouteDto{}
+	if application != "" {
+		crDto.Application = application
+		routeDto, err = routeService.FindConditionRoute(crDto)
+	} else if service != "" {
+		crDto.Service = service
+		crDto.ServiceVersion = serviceVersion
+		crDto.ServiceGroup = serviceGroup
+		routeDto, err = routeService.FindConditionRoute(crDto)
+	} else {
+		c.JSON(http.StatusInternalServerError, gin.H{
+			"error": "Either Service or application is required.",
+		})
+		return
+	}
 
-	tagRoute, err := tagRouteService.FindTagRoute(application)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -95,15 +107,13 @@ func SearchRoutes(c *gin.Context) {
 	}
 	c.JSON(http.StatusOK, gin.H{
 		"code": 1,
-		"data": []model.TagRouteDto{tagRoute},
+		"data": []model.ConditionRouteDto{routeDto},
 	})
 }
 
-func DetailRoute(c *gin.Context) {
+func DetailConditionRoute(c *gin.Context) {
 	id := c.Param("id")
-	id = strings.ReplaceAll(id, "*", "/")
-
-	tagRoute, err := tagRouteService.FindTagRoute(id)
+	routeDto, err := routeService.FindConditionRouteById(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -112,15 +122,13 @@ func DetailRoute(c *gin.Context) {
 	}
 	c.JSON(http.StatusOK, gin.H{
 		"code": 1,
-		"data": tagRoute,
+		"data": routeDto,
 	})
 }
 
-func DeleteRoute(c *gin.Context) {
+func DeleteConditionRoute(c *gin.Context) {
 	id := c.Param("id")
-	id = strings.ReplaceAll(id, "*", "/")
-
-	err := tagRouteService.DeleteTagRoute(id)
+	err := routeService.DeleteConditionRoute(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -133,11 +141,9 @@ func DeleteRoute(c *gin.Context) {
 	})
 }
 
-func EnableRoute(c *gin.Context) {
+func EnableConditionRoute(c *gin.Context) {
 	id := c.Param("id")
-	id = strings.ReplaceAll(id, "*", "/")
-
-	err := tagRouteService.EnableTagRoute(id)
+	err := routeService.EnableConditionRoute(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -150,11 +156,9 @@ func EnableRoute(c *gin.Context) {
 	})
 }
 
-func DisableRoute(c *gin.Context) {
+func DisableConditionRoute(c *gin.Context) {
 	id := c.Param("id")
-	id = strings.ReplaceAll(id, "*", "/")
-
-	err := tagRouteService.DisableTagRoute(id)
+	err := routeService.DisableConditionRoute(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
diff --git a/pkg/admin/handlers/tag_route.go b/pkg/admin/handlers/tag_route.go
index baa17d06..cd1dc7eb 100644
--- a/pkg/admin/handlers/tag_route.go
+++ b/pkg/admin/handlers/tag_route.go
@@ -27,7 +27,7 @@ import (
 	"github.com/gin-gonic/gin"
 )
 
-var tagRouteService services.TagRoutesService = &services.TagRoutesServiceImpl{
+var routeService services.RouteService = &services.RouteServiceImpl{
 	GovernanceConfig: &config.GovernanceConfigImpl{},
 }
 
@@ -38,7 +38,7 @@ func CreateRule(c *gin.Context) {
 		panic(err)
 	}
 
-	err = tagRouteService.CreateTagRoute(tagRouteDto)
+	err = routeService.CreateTagRoute(tagRouteDto)
 
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
@@ -61,7 +61,7 @@ func UpdateRule(c *gin.Context) {
 	id := c.Param("id")
 	id = strings.ReplaceAll(id, "*", "/")
 
-	_, err = tagRouteService.FindTagRoute(id)
+	_, err = routeService.FindTagRoute(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -69,7 +69,7 @@ func UpdateRule(c *gin.Context) {
 		return
 	}
 
-	err = tagRouteService.UpdateTagRoute(tagRouteDto)
+	err = routeService.UpdateTagRoute(tagRouteDto)
 
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
@@ -86,7 +86,7 @@ func UpdateRule(c *gin.Context) {
 func SearchRoutes(c *gin.Context) {
 	application := c.Query("application")
 
-	tagRoute, err := tagRouteService.FindTagRoute(application)
+	tagRoute, err := routeService.FindTagRoute(application)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -103,7 +103,7 @@ func DetailRoute(c *gin.Context) {
 	id := c.Param("id")
 	id = strings.ReplaceAll(id, "*", "/")
 
-	tagRoute, err := tagRouteService.FindTagRoute(id)
+	tagRoute, err := routeService.FindTagRoute(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -120,7 +120,7 @@ func DeleteRoute(c *gin.Context) {
 	id := c.Param("id")
 	id = strings.ReplaceAll(id, "*", "/")
 
-	err := tagRouteService.DeleteTagRoute(id)
+	err := routeService.DeleteTagRoute(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -137,7 +137,7 @@ func EnableRoute(c *gin.Context) {
 	id := c.Param("id")
 	id = strings.ReplaceAll(id, "*", "/")
 
-	err := tagRouteService.EnableTagRoute(id)
+	err := routeService.EnableTagRoute(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
@@ -154,7 +154,7 @@ func DisableRoute(c *gin.Context) {
 	id := c.Param("id")
 	id = strings.ReplaceAll(id, "*", "/")
 
-	err := tagRouteService.DisableTagRoute(id)
+	err := routeService.DisableTagRoute(id)
 	if err != nil {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"error": err.Error(),
diff --git a/pkg/admin/services/tag_route_service.go b/pkg/admin/model/condition_route.go
similarity index 55%
copy from pkg/admin/services/tag_route_service.go
copy to pkg/admin/model/condition_route.go
index d9facbd4..d4728a08 100644
--- a/pkg/admin/services/tag_route_service.go
+++ b/pkg/admin/model/condition_route.go
@@ -15,15 +15,26 @@
  * limitations under the License.
  */
 
-package services
+package model
 
-import "github.com/apache/dubbo-admin/pkg/admin/model"
+type ConditionRouteDto struct {
+	Base
 
-type TagRoutesService interface {
-	CreateTagRoute(model.TagRouteDto) error
-	UpdateTagRoute(model.TagRouteDto) error
-	DeleteTagRoute(string) error
-	FindTagRoute(string) (model.TagRouteDto, error)
-	EnableTagRoute(string) error
-	DisableTagRoute(string) error
+	Conditions []string `json:"conditions" binding:"required"`
+
+	Priority      int    `json:"priority"`
+	Enabled       bool   `json:"enabled" binding:"required"`
+	Force         bool   `json:"force"`
+	Runtime       bool   `json:"runtime"`
+	ConfigVersion string `json:"configVersion" binding:"required"`
+}
+
+type ConditionRoute struct {
+	Priority   int      `json:"priority"`
+	Enabled    bool     `json:"enabled"`
+	Force      bool     `json:"force"`
+	Runtime    bool     `json:"runtime"`
+	Key        string   `json:"key"`
+	Scope      string   `json:"scope"`
+	Conditions []string `json:"conditions"`
 }
diff --git a/pkg/admin/router/router.go b/pkg/admin/router/router.go
index f370b749..ebe157c4 100644
--- a/pkg/admin/router/router.go
+++ b/pkg/admin/router/router.go
@@ -56,5 +56,16 @@ func InitRouter() *gin.Engine {
 		tagRoute.PUT("/disable/:id", handlers.DisableRoute)
 	}
 
+	conditionRoute := router.Group("/api/:env/rules/route/condition")
+	{
+		conditionRoute.POST("/", handlers.CreateConditionRule)
+		conditionRoute.PUT("/:id", handlers.UpdateConditionRule)
+		conditionRoute.GET("/", handlers.SearchConditionRoutes)
+		conditionRoute.GET("/:id", handlers.DetailConditionRoute)
+		conditionRoute.DELETE("/:id", handlers.DeleteConditionRoute)
+		conditionRoute.PUT("/enable/:id", handlers.EnableConditionRoute)
+		conditionRoute.PUT("/disable/:id", handlers.DisableConditionRoute)
+	}
+
 	return router
 }
diff --git a/pkg/admin/services/tag_route_service.go b/pkg/admin/services/route_service.go
similarity index 73%
rename from pkg/admin/services/tag_route_service.go
rename to pkg/admin/services/route_service.go
index d9facbd4..90aab3a0 100644
--- a/pkg/admin/services/tag_route_service.go
+++ b/pkg/admin/services/route_service.go
@@ -19,11 +19,19 @@ package services
 
 import "github.com/apache/dubbo-admin/pkg/admin/model"
 
-type TagRoutesService interface {
+type RouteService interface {
 	CreateTagRoute(model.TagRouteDto) error
 	UpdateTagRoute(model.TagRouteDto) error
 	DeleteTagRoute(string) error
 	FindTagRoute(string) (model.TagRouteDto, error)
 	EnableTagRoute(string) error
 	DisableTagRoute(string) error
+
+	CreateConditionRoute(model.ConditionRouteDto) error
+	UpdateConditionRoute(model.ConditionRouteDto) error
+	DeleteConditionRoute(string) error
+	FindConditionRouteById(string) (model.ConditionRouteDto, error)
+	FindConditionRoute(model.ConditionRouteDto) (model.ConditionRouteDto, error)
+	EnableConditionRoute(string) error
+	DisableConditionRoute(string) error
 }
diff --git a/pkg/admin/services/route_service_impl.go b/pkg/admin/services/route_service_impl.go
new file mode 100644
index 00000000..1303106f
--- /dev/null
+++ b/pkg/admin/services/route_service_impl.go
@@ -0,0 +1,268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package services
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/apache/dubbo-admin/pkg/admin/config"
+	"github.com/apache/dubbo-admin/pkg/admin/constant"
+	"github.com/apache/dubbo-admin/pkg/admin/model"
+	"github.com/apache/dubbo-admin/pkg/admin/util"
+)
+
+type RouteServiceImpl struct {
+	GovernanceConfig config.GovernanceConfig
+}
+
+func (t *RouteServiceImpl) CreateTagRoute(tagRoute model.TagRouteDto) error {
+	id := util.BuildServiceKey(tagRoute.Base)
+	path := getRoutePath(id, constant.TagRoute)
+	store := convertTagRouteToStore(tagRoute)
+	obj, _ := util.DumpObject(store)
+	return t.GovernanceConfig.SetConfig(path, obj)
+}
+
+func (t *RouteServiceImpl) UpdateTagRoute(tagRoute model.TagRouteDto) error {
+	id := util.BuildServiceKey(tagRoute.Base)
+	path := getRoutePath(id, constant.TagRoute)
+	cfg, _ := t.GovernanceConfig.GetConfig(path)
+	if cfg == "" {
+		return fmt.Errorf("tag route %s not found", id)
+	}
+	store := convertTagRouteToStore(tagRoute)
+	obj, _ := util.DumpObject(store)
+	return t.GovernanceConfig.SetConfig(path, obj)
+}
+
+func (t *RouteServiceImpl) DeleteTagRoute(id string) error {
+	path := getRoutePath(id, constant.TagRoute)
+	return t.GovernanceConfig.DeleteConfig(path)
+}
+
+func (t *RouteServiceImpl) FindTagRoute(id string) (model.TagRouteDto, error) {
+	path := getRoutePath(id, constant.TagRoute)
+	cfg, err := t.GovernanceConfig.GetConfig(path)
+	if cfg != "" {
+		var tagRoute model.TagRoute
+		_ = util.LoadObject(cfg, &tagRoute)
+		return convertTagRouteToDto(tagRoute), nil
+	}
+	return model.TagRouteDto{}, err
+}
+
+func (t *RouteServiceImpl) EnableTagRoute(id string) error {
+	path := getRoutePath(id, constant.TagRoute)
+	cfg, err := t.GovernanceConfig.GetConfig(path)
+	if cfg != "" {
+		var tagRoute model.TagRoute
+		_ = util.LoadObject(cfg, &tagRoute)
+		tagRoute.Enabled = true
+		obj, _ := util.DumpObject(tagRoute)
+		return t.GovernanceConfig.SetConfig(path, obj)
+	}
+	return err
+}
+
+func (t *RouteServiceImpl) DisableTagRoute(id string) error {
+	path := getRoutePath(id, constant.TagRoute)
+	cfg, err := t.GovernanceConfig.GetConfig(path)
+	if cfg != "" {
+		var tagRoute model.TagRoute
+		_ = util.LoadObject(cfg, &tagRoute)
+		tagRoute.Enabled = false
+		obj, _ := util.DumpObject(tagRoute)
+		return t.GovernanceConfig.SetConfig(path, obj)
+	}
+	return err
+}
+
+func (t *RouteServiceImpl) CreateConditionRoute(conditionRouteDto model.ConditionRouteDto) error {
+	id := util.BuildServiceKey(conditionRouteDto.Base)
+	path := getRoutePath(id, constant.ConditionRoute)
+	existConfig, _ := t.GovernanceConfig.GetConfig(path)
+
+	var existRule model.ConditionRoute
+	if existConfig != "" {
+		_ = util.LoadObject(existConfig, &existRule)
+	}
+	store := convertConditionRouteToStore(existRule, conditionRouteDto)
+
+	obj, _ := util.DumpObject(store)
+	return t.GovernanceConfig.SetConfig(path, obj)
+}
+
+func (t *RouteServiceImpl) UpdateConditionRoute(conditionRouteDto model.ConditionRouteDto) error {
+	id := util.BuildServiceKey(conditionRouteDto.Base)
+	path := getRoutePath(id, constant.ConditionRoute)
+	cfg, err := t.GovernanceConfig.GetConfig(path)
+	if err != nil {
+		return err
+	}
+	if cfg == "" {
+		return fmt.Errorf("no existing condition route for path: %s", path)
+	}
+
+	var existRule model.ConditionRoute
+	_ = util.LoadObject(cfg, &existRule)
+	store := convertConditionRouteToStore(existRule, conditionRouteDto)
+
+	obj, _ := util.DumpObject(store)
+	return t.GovernanceConfig.SetConfig(path, obj)
+}
+
+func (t *RouteServiceImpl) DeleteConditionRoute(id string) error {
+	path := getRoutePath(id, constant.ConditionRoute)
+	return t.GovernanceConfig.DeleteConfig(path)
+}
+
+func (t *RouteServiceImpl) FindConditionRouteById(id string) (model.ConditionRouteDto, error) {
+	path := getRoutePath(id, constant.ConditionRoute)
+	cfg, err := t.GovernanceConfig.GetConfig(path)
+	if err != nil {
+		return model.ConditionRouteDto{}, err
+	}
+	if cfg != "" {
+		var conditionRoute model.ConditionRoute
+		_ = util.LoadObject(cfg, &conditionRoute)
+		dto := convertConditionRouteToDto(conditionRoute)
+		if dto.Service != "" {
+			dto.Service = strings.ReplaceAll(dto.Service, "*", "/")
+		}
+		detachResult := detachId(id)
+		if len(detachResult) > 1 {
+			dto.ServiceVersion = detachResult[1]
+		}
+		if len(detachResult) > 2 {
+			dto.ServiceGroup = detachResult[2]
+		}
+		dto.ID = id
+		return dto, nil
+	}
+	return model.ConditionRouteDto{}, nil
+}
+
+func (t *RouteServiceImpl) FindConditionRoute(dto model.ConditionRouteDto) (model.ConditionRouteDto, error) {
+	return t.FindConditionRouteById(util.BuildServiceKey(dto.Base))
+}
+
+func (t *RouteServiceImpl) EnableConditionRoute(id string) error {
+	path := getRoutePath(id, constant.ConditionRoute)
+	cfg, err := t.GovernanceConfig.GetConfig(path)
+	if err != nil {
+		return err
+	}
+	if cfg != "" {
+		var conditionRoute model.ConditionRoute
+		_ = util.LoadObject(cfg, &conditionRoute)
+		conditionRoute.Enabled = true
+		obj, _ := util.DumpObject(conditionRoute)
+		return t.GovernanceConfig.SetConfig(path, obj)
+	}
+	return fmt.Errorf("no existing condition route for path: %s", path)
+}
+
+func (t *RouteServiceImpl) DisableConditionRoute(id string) error {
+	path := getRoutePath(id, constant.ConditionRoute)
+	cfg, err := t.GovernanceConfig.GetConfig(path)
+	if err != nil {
+		return err
+	}
+	if cfg != "" {
+		var conditionRoute model.ConditionRoute
+		_ = util.LoadObject(cfg, &conditionRoute)
+		conditionRoute.Enabled = false
+		obj, _ := util.DumpObject(conditionRoute)
+		return t.GovernanceConfig.SetConfig(path, obj)
+	}
+	return fmt.Errorf("no existing condition route for path: %s", path)
+}
+
+func getRoutePath(key string, routeType string) string {
+	key = strings.ReplaceAll(key, "/", "*")
+	if routeType == constant.ConditionRoute {
+		return key + constant.ConditionRuleSuffix
+	} else {
+		return key + constant.TagRuleSuffix
+	}
+}
+
+func convertTagRouteToStore(tagRoute model.TagRouteDto) model.TagRoute {
+	var store model.TagRoute
+	store.Key = tagRoute.Application
+	store.Enabled = tagRoute.Enabled
+	store.Force = tagRoute.Force
+	store.Priority = tagRoute.Priority
+	store.Runtime = tagRoute.Runtime
+	store.Tags = tagRoute.Tags
+	return store
+}
+
+func convertTagRouteToDto(tagRoute model.TagRoute) model.TagRouteDto {
+	var dto model.TagRouteDto
+	dto.Application = tagRoute.Key
+	dto.Enabled = tagRoute.Enabled
+	dto.Force = tagRoute.Force
+	dto.Priority = tagRoute.Priority
+	dto.Runtime = tagRoute.Runtime
+	dto.Tags = tagRoute.Tags
+	return dto
+}
+
+func convertConditionRouteToStore(existRule model.ConditionRoute, conditionRouteDto model.ConditionRouteDto) model.ConditionRoute {
+	if existRule.Key == "" || existRule.Scope == "" {
+		existRule = model.ConditionRoute{}
+		if conditionRouteDto.Application != "" {
+			existRule.Key = conditionRouteDto.Application
+			existRule.Scope = constant.Application
+		} else {
+			existRule.Key = strings.ReplaceAll(conditionRouteDto.Service, "/", "*")
+			existRule.Scope = constant.Service
+		}
+	}
+	existRule.Enabled = conditionRouteDto.Enabled
+	existRule.Force = conditionRouteDto.Force
+	existRule.Priority = conditionRouteDto.Priority
+	existRule.Runtime = conditionRouteDto.Runtime
+	existRule.Conditions = conditionRouteDto.Conditions
+	return existRule
+}
+
+func convertConditionRouteToDto(conditionRoute model.ConditionRoute) model.ConditionRouteDto {
+	var dto model.ConditionRouteDto
+	if conditionRoute.Scope == constant.Application {
+		dto.Application = conditionRoute.Key
+	} else {
+		dto.Service = conditionRoute.Key
+	}
+	dto.Enabled = conditionRoute.Enabled
+	dto.Force = conditionRoute.Force
+	dto.Priority = conditionRoute.Priority
+	dto.Runtime = conditionRoute.Runtime
+	dto.Conditions = conditionRoute.Conditions
+	return dto
+}
+
+func detachId(id string) []string {
+	if strings.Contains(id, constant.Colon) {
+		return strings.Split(id, constant.Colon)
+	} else {
+		return []string{id}
+	}
+}
diff --git a/pkg/admin/services/tag_route_service_impl.go b/pkg/admin/services/tag_route_service_impl.go
deleted file mode 100644
index 54feb717..00000000
--- a/pkg/admin/services/tag_route_service_impl.go
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package services
-
-import (
-	"fmt"
-	"strings"
-
-	"github.com/apache/dubbo-admin/pkg/admin/config"
-	"github.com/apache/dubbo-admin/pkg/admin/constant"
-	"github.com/apache/dubbo-admin/pkg/admin/model"
-	"github.com/apache/dubbo-admin/pkg/admin/util"
-)
-
-type TagRoutesServiceImpl struct {
-	GovernanceConfig config.GovernanceConfig
-}
-
-func (t *TagRoutesServiceImpl) CreateTagRoute(tagRoute model.TagRouteDto) error {
-	id := util.BuildServiceKey(tagRoute.Base)
-	path := getTagRoutePath(id, constant.TagRoute)
-	store := convertTagRouteToStore(tagRoute)
-	obj, _ := util.DumpObject(store)
-	return t.GovernanceConfig.SetConfig(path, obj)
-}
-
-func (t *TagRoutesServiceImpl) UpdateTagRoute(tagRoute model.TagRouteDto) error {
-	id := util.BuildServiceKey(tagRoute.Base)
-	path := getTagRoutePath(id, constant.TagRoute)
-	cfg, _ := t.GovernanceConfig.GetConfig(path)
-	if cfg == "" {
-		return fmt.Errorf("tag route %s not found", id)
-	}
-	store := convertTagRouteToStore(tagRoute)
-	obj, _ := util.DumpObject(store)
-	return t.GovernanceConfig.SetConfig(path, obj)
-}
-
-func (t *TagRoutesServiceImpl) DeleteTagRoute(id string) error {
-	path := getTagRoutePath(id, constant.TagRoute)
-	return t.GovernanceConfig.DeleteConfig(path)
-}
-
-func (t *TagRoutesServiceImpl) FindTagRoute(id string) (model.TagRouteDto, error) {
-	path := getTagRoutePath(id, constant.TagRoute)
-	cfg, err := t.GovernanceConfig.GetConfig(path)
-	if cfg != "" {
-		var tagRoute model.TagRoute
-		_ = util.LoadObject(cfg, &tagRoute)
-		return convertTagRouteToDto(tagRoute), nil
-	}
-	return model.TagRouteDto{}, err
-}
-
-func (t *TagRoutesServiceImpl) EnableTagRoute(id string) error {
-	path := getTagRoutePath(id, constant.TagRoute)
-	cfg, err := t.GovernanceConfig.GetConfig(path)
-	if cfg != "" {
-		var tagRoute model.TagRoute
-		_ = util.LoadObject(cfg, &tagRoute)
-		tagRoute.Enabled = true
-		obj, _ := util.DumpObject(tagRoute)
-		return t.GovernanceConfig.SetConfig(path, obj)
-	}
-	return err
-}
-
-func (t *TagRoutesServiceImpl) DisableTagRoute(id string) error {
-	path := getTagRoutePath(id, constant.TagRoute)
-	cfg, err := t.GovernanceConfig.GetConfig(path)
-	if cfg != "" {
-		var tagRoute model.TagRoute
-		_ = util.LoadObject(cfg, &tagRoute)
-		tagRoute.Enabled = false
-		obj, _ := util.DumpObject(tagRoute)
-		return t.GovernanceConfig.SetConfig(path, obj)
-	}
-	return err
-}
-
-func getTagRoutePath(key string, routeType string) string {
-	key = strings.ReplaceAll(key, "*", "/")
-	if routeType == constant.ConditionRoute {
-		return key + constant.ConditionRuleSuffix
-	} else {
-		return key + constant.TagRuleSuffix
-	}
-}
-
-func convertTagRouteToStore(tagRoute model.TagRouteDto) model.TagRoute {
-	var store model.TagRoute
-	store.Key = tagRoute.Application
-	store.Enabled = tagRoute.Enabled
-	store.Force = tagRoute.Force
-	store.Priority = tagRoute.Priority
-	store.Runtime = tagRoute.Runtime
-	store.Tags = tagRoute.Tags
-	return store
-}
-
-func convertTagRouteToDto(tagRoute model.TagRoute) model.TagRouteDto {
-	var dto model.TagRouteDto
-	dto.Application = tagRoute.Key
-	dto.Enabled = tagRoute.Enabled
-	dto.Force = tagRoute.Force
-	dto.Priority = tagRoute.Priority
-	dto.Runtime = tagRoute.Runtime
-	dto.Tags = tagRoute.Tags
-	return dto
-}