dubbo 2.7 & compatible with dubbo2.6
diff --git a/dubbo-admin-backend/README.md b/dubbo-admin-backend/README.md
new file mode 100644
index 0000000..49d5c21
--- /dev/null
+++ b/dubbo-admin-backend/README.md
@@ -0,0 +1,6 @@
+## Dubbo Admin后端配置
+当前版本的的Dubbo Aadmin支持Dubbo2.7的新特性(元数据展示,应用级别的配置),同时也兼容Dubbo2.6的用法,两个版本的配置不同,具体介绍如下:  
+* application.properties配置
+  * dubbo.config.center: 2.7的配置,推荐用法,填写配置中心的地址,并且在配置中心的相应目录下配置注册中心和元数据中心的地址,Dubbo Admin会根据相应的协议,初始化对应的客户端,实现对配置中心,元数据中心的访问
+  * dubbo.registry.address: 2.6的配置,只配置注册中心的地址。采用此配置,Dubbo Admin会把配置,元数据相关的内容也写入注册中心的不同目录下
+  * 两种配置,都可以兼容Dubbo2.6和2.7的版本,即使配置了dubbo.config.center,对于2.6版本的客户端,也会收到对应版本的路由,动态配置规则,并且按照规则内容生效
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/Constants.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/Constants.java
index 427affa..b429ca6 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/Constants.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/Constants.java
@@ -18,6 +18,9 @@
 package org.apache.dubbo.admin.common.util;
 
 
+import java.util.HashSet;
+import java.util.Set;
+
 public class Constants {
 
     public static final String REGISTRY_ADDRESS = "dubbo.registry.address";
@@ -29,9 +32,18 @@
     public static final String CATEGORY_KEY = "category";
     public static final String ROUTERS_CATEGORY = "routers";
     public static final String CONDITION_ROUTE = "condition_route";
+    public static final String CONFIGURATOR = "configurators";
     public static final String TAG_ROUTE = "tag_route";
-
-
     public static final String COMPATIBLE_CONFIG = "compatible_config";
+    public static final String WEIGHT = "weight";
+    public static final String BALANCING = "balancing";
+    public static final String SERVICE = "service";
+    public static final String APPLICATION = "application";
+    public static final Set<String> CONFIGS = new HashSet<>();
+
+    static {
+        CONFIGS.add(WEIGHT);
+        CONFIGS.add(BALANCING);
+    }
 
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/ConvertUtil.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/ConvertUtil.java
index 9f3eb4c..d7b85d4 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/ConvertUtil.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/ConvertUtil.java
@@ -16,6 +16,7 @@
  */
 package org.apache.dubbo.admin.common.util;
 
+import org.apache.dubbo.admin.model.dto.BaseDTO;
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.utils.StringUtils;
 
@@ -53,4 +54,45 @@
 
         return ret;
     }
+
+    public static String getIdFromDTO(BaseDTO baseDTO) {
+        String id;
+        if (StringUtils.isNotEmpty(baseDTO.getApplication())) {
+            id = baseDTO.getApplication();
+        } else {
+            id = baseDTO.getService();
+        }
+        return id;
+    }
+
+    public static String getScopeFromDTO(BaseDTO baseDTO) {
+        if (StringUtils.isNotEmpty(baseDTO.getApplication())) {
+            return org.apache.dubbo.admin.common.util.Constants.APPLICATION;
+        } else {
+            return org.apache.dubbo.admin.common.util.Constants.SERVICE;
+        }
+    }
+
+//    public static <T extends BaseDTO> T convertDTOtoStore(T dto) {
+//        if (StringUtils.isNotEmpty(dto.getApplication())) {
+//            dto.setScope("application");
+//            dto.setKey(dto.getApplication());
+//        } else {
+//            dto.setScope("service");
+//            dto.setKey(dto.getService());
+//        }
+//        return dto;
+//    }
+//
+//    public static <T extends BaseDTO> T convertDTOtoDisplay(T dto) {
+//        if (dto == null) {
+//            return null;
+//        }
+//        if(dto.getScope().equals("application")) {
+//            dto.setApplication(dto.getKey());
+//        } else {
+//            dto.setService(dto.getKey());
+//        }
+//        return dto;
+//    }
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/OverrideUtils.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/OverrideUtils.java
index 87778dd..d9b3115 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/OverrideUtils.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/OverrideUtils.java
@@ -1,137 +1,216 @@
-///*
-// * 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 org.apache.dubbo.admin.common.util;
-//
-//import org.apache.dubbo.common.utils.StringUtils;
-//import org.apache.dubbo.admin.model.domain.LoadBalance;
-//import org.apache.dubbo.admin.model.domain.Override;
-//import org.apache.dubbo.admin.model.domain.Weight;
-//
-//import java.util.ArrayList;
-//import java.util.Arrays;
-//import java.util.List;
-//import java.util.Map;
-//
-///**
-// * OverrideUtils.java
-// *
-// */
-//public class OverrideUtils {
-//    public static List<Weight> overridesToWeights(List<Override> overrides) {
-//        List<Weight> weights = new ArrayList<Weight>();
-//        if (overrides == null) {
-//            return weights;
-//        }
-//        for (Override o : overrides) {
-//            if (StringUtils.isEmpty(o.getParams())) {
-//                continue;
-//            } else {
-//                Map<String, String> params = StringUtils.parseQueryString(o.getParams());
-//                for (Map.Entry<String, String> entry : params.entrySet()) {
-//                    if (entry.getKey().equals("weight")) {
-//                        Weight weight = new Weight();
-//                        weight.setAddress(o.getAddress());
-//                        weight.setId(o.getId());
-//                        weight.setHash(o.getHash());
-//                        weight.setService(o.getService());
-//                        weight.setWeight(Integer.valueOf(entry.getValue()));
-//                        weights.add(weight);
-//                    }
-//                }
-//            }
-//        }
-//        return weights;
-//    }
-//
-//    public static Weight overrideToWeight(Override override) {
-//        List<Weight> weights = OverrideUtils.overridesToWeights(Arrays.asList(override));
-//        if (weights != null && weights.size() > 0) {
-//            return overridesToWeights(Arrays.asList(override)).get(0);
-//        }
-//        return null;
-//    }
-//
-//    public static Override weightToOverride(Weight weight) {
-//        Override override = new Override();
-//        override.setId(weight.getId());
-//        override.setHash(weight.getHash());
-//        override.setAddress(weight.getAddress());
-//        override.setEnabled(true);
-//        override.setParams("weight=" + weight.getWeight());
-//        override.setService(weight.getService());
-//        return override;
-//    }
-//
-//    public static List<LoadBalance> overridesToLoadBalances(List<Override> overrides) {
-//        List<LoadBalance> loadBalances = new ArrayList<LoadBalance>();
-//        if (overrides == null) {
-//            return loadBalances;
-//        }
-//        for (Override o : overrides) {
-//            if (StringUtils.isEmpty(o.getParams())) {
-//                continue;
-//            } else {
-//                Map<String, String> params = StringUtils.parseQueryString(o.getParams());
-//                for (Map.Entry<String, String> entry : params.entrySet()) {
-//                    if (entry.getKey().endsWith("loadbalance")) {
-//                        LoadBalance loadBalance = new LoadBalance();
-//                        String method = null;
-//                        if (entry.getKey().endsWith(".loadbalance")) {
-//                            method = entry.getKey().split(".loadbalance")[0];
-//                        } else {
-//                            method = "*";
-//                        }
-//
-//                        loadBalance.setMethod(method);
-//                        loadBalance.setId(o.getId());
-//                        loadBalance.setHash(o.getHash());
-//                        loadBalance.setService(o.getService());
-//                        loadBalance.setStrategy(entry.getValue());
-//                        loadBalances.add(loadBalance);
-//
-//                    }
-//                }
-//            }
-//        }
-//        return loadBalances;
-//    }
-//
-//    public static LoadBalance overrideToLoadBalance(Override override) {
-//        List<LoadBalance> loadBalances = OverrideUtils.overridesToLoadBalances(Arrays.asList(override));
-//        if (loadBalances != null && loadBalances.size() > 0) {
-//            return loadBalances.get(0);
-//        }
-//        return null;
-//    }
-//
-//    public static Override loadBalanceToOverride(LoadBalance loadBalance) {
-//        Override override = new Override();
-//        override.setId(loadBalance.getId());
-//        override.setHash(loadBalance.getHash());
-//        override.setService(loadBalance.getService());
-//        override.setEnabled(true);
-//        String method = loadBalance.getMethod();
-//        String strategy = loadBalance.getStrategy();
-//        if (StringUtils.isEmpty(method) || method.equals("*")) {
-//            override.setParams("loadbalance=" + strategy);
-//        } else {
-//            override.setParams(method + ".loadbalance=" + strategy);
-//        }
-//        return override;
-//    }
-//
-//}
+/*
+ * 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 org.apache.dubbo.admin.common.util;
+
+import org.apache.dubbo.admin.model.domain.*;
+import org.apache.dubbo.admin.model.domain.Override;
+import org.apache.dubbo.admin.model.dto.BalancingDTO;
+import org.apache.dubbo.admin.model.dto.Config;
+import org.apache.dubbo.admin.model.dto.DynamicConfigDTO;
+import org.apache.dubbo.admin.model.dto.WeightDTO;
+import org.apache.dubbo.admin.model.store.OverrideConfig;
+import org.apache.dubbo.admin.model.store.OverrideDTO;
+import org.apache.dubbo.common.utils.StringUtils;
+
+import java.util.*;
+
+/**
+ * OverrideUtils.java
+ *
+ */
+public class OverrideUtils {
+    public static List<Weight> overridesToWeights(List<Override> overrides) {
+        List<Weight> weights = new ArrayList<Weight>();
+        if (overrides == null) {
+            return weights;
+        }
+        for (Override o : overrides) {
+            if (StringUtils.isEmpty(o.getParams())) {
+                continue;
+            } else {
+                Map<String, String> params = StringUtils.parseQueryString(o.getParams());
+                for (Map.Entry<String, String> entry : params.entrySet()) {
+                    if (entry.getKey().equals("weight")) {
+                        Weight weight = new Weight();
+                        weight.setAddress(o.getAddress());
+                        weight.setId(o.getId());
+                        weight.setHash(o.getHash());
+                        weight.setService(o.getService());
+                        weight.setWeight(Integer.valueOf(entry.getValue()));
+                        weights.add(weight);
+                    }
+                }
+            }
+        }
+        return weights;
+    }
+
+    public static OverrideConfig weightDTOtoConfig(WeightDTO weightDTO) {
+        OverrideConfig overrideConfig = new OverrideConfig();
+        overrideConfig.setType("weight");
+        overrideConfig.setEnabled(true);
+        overrideConfig.setAddresses(weightDTO.getAddresses());
+        Map<String, Object> parameters = new HashMap<>();
+        parameters.put("weight", weightDTO.getWeight());
+        overrideConfig.setParameters(parameters);
+        return overrideConfig;
+    }
+
+    public static DynamicConfigDTO createFromOverride(OverrideDTO overrideDTO) {
+        DynamicConfigDTO dynamicConfigDTO = new DynamicConfigDTO();
+        dynamicConfigDTO.setApiVersion(overrideDTO.getApiVersion());
+        List<OverrideConfig> configs = new ArrayList<>();
+        for (OverrideConfig overrideConfig : overrideDTO.getConfigs()) {
+            if (overrideConfig.getType() == null) {
+                configs.add(overrideConfig);
+            }
+        }
+        dynamicConfigDTO.setConfigs(configs);
+        if (overrideDTO.getScope().equals(Constants.APPLICATION)) {
+            dynamicConfigDTO.setApplication(overrideDTO.getKey());
+        } else {
+            dynamicConfigDTO.setService(overrideDTO.getKey());
+        }
+        return dynamicConfigDTO;
+    }
+    public static OverrideDTO createFromDynamicConfig(DynamicConfigDTO dynamicConfigDTO) {
+        OverrideDTO overrideDTO = new OverrideDTO();
+        if (StringUtils.isNotEmpty(dynamicConfigDTO.getApplication())) {
+            overrideDTO.setScope(Constants.APPLICATION);
+            overrideDTO.setKey(dynamicConfigDTO.getApplication());
+        } else {
+            overrideDTO.setScope(Constants.SERVICE);
+            overrideDTO.setKey(dynamicConfigDTO.getService());
+        }
+        overrideDTO.setApiVersion(dynamicConfigDTO.getApiVersion());
+        overrideDTO.setConfigs(dynamicConfigDTO.getConfigs());
+        return overrideDTO;
+    }
+
+    public static OverrideConfig balanceDTOtoConfig(BalancingDTO balancingDTO) {
+        OverrideConfig overrideConfig = new OverrideConfig();
+        overrideConfig.setType("balancing");
+        overrideConfig.setEnabled(true);
+        Map<String, Object> parameters = new HashMap<>();
+        parameters.put("method", balancingDTO.getMethodName());
+        parameters.put("strategy", balancingDTO.getStrategy());
+        overrideConfig.setParameters(parameters);
+        return overrideConfig;
+    }
+
+    public static WeightDTO configtoWeightDTO(OverrideConfig config, String scope, String key) {
+        WeightDTO weightDTO = new WeightDTO();
+        if (scope.equals(Constants.APPLICATION)) {
+            weightDTO.setApplication(key);
+        } else {
+            weightDTO.setService(key);
+        }
+        weightDTO.setWeight((int)config.getParameters().get("weight"));
+        weightDTO.setAddresses(config.getAddresses());
+        return weightDTO;
+    }
+
+    public static BalancingDTO configtoBalancingDTO(OverrideConfig config, String scope, String key) {
+        BalancingDTO balancingDTO = new BalancingDTO();
+        if (scope.equals(Constants.APPLICATION)) {
+            balancingDTO.setApplication(key);
+        } else {
+            balancingDTO.setService(key);
+        }
+        balancingDTO.setStrategy((String)config.getParameters().get("strategy"));
+        balancingDTO.setMethodName((String)config.getParameters().get("method"));
+        return balancingDTO;
+    }
+
+    public static Weight overrideToWeight(Override override) {
+        List<Weight> weights = OverrideUtils.overridesToWeights(Arrays.asList(override));
+        if (weights != null && weights.size() > 0) {
+            return overridesToWeights(Arrays.asList(override)).get(0);
+        }
+        return null;
+    }
+
+    public static Override weightToOverride(Weight weight) {
+        Override override = new Override();
+        override.setId(weight.getId());
+        override.setHash(weight.getHash());
+        override.setAddress(weight.getAddress());
+        override.setEnabled(true);
+        override.setParams("weight=" + weight.getWeight());
+        override.setService(weight.getService());
+        return override;
+    }
+
+    public static List<LoadBalance> overridesToLoadBalances(List<Override> overrides) {
+        List<LoadBalance> loadBalances = new ArrayList<>();
+        if (overrides == null) {
+            return loadBalances;
+        }
+        for (Override o : overrides) {
+            if (StringUtils.isEmpty(o.getParams())) {
+                continue;
+            } else {
+                Map<String, String> params = StringUtils.parseQueryString(o.getParams());
+                for (Map.Entry<String, String> entry : params.entrySet()) {
+                    if (entry.getKey().endsWith("loadbalance")) {
+                        LoadBalance loadBalance = new LoadBalance();
+                        String method = null;
+                        if (entry.getKey().endsWith(".loadbalance")) {
+                            method = entry.getKey().split(".loadbalance")[0];
+                        } else {
+                            method = "*";
+                        }
+
+                        loadBalance.setMethod(method);
+                        loadBalance.setId(o.getId());
+                        loadBalance.setHash(o.getHash());
+                        loadBalance.setService(o.getService());
+                        loadBalance.setStrategy(entry.getValue());
+                        loadBalances.add(loadBalance);
+
+                    }
+                }
+            }
+        }
+        return loadBalances;
+    }
+
+    public static LoadBalance overrideToLoadBalance(Override override) {
+        List<LoadBalance> loadBalances = OverrideUtils.overridesToLoadBalances(Arrays.asList(override));
+        if (loadBalances != null && loadBalances.size() > 0) {
+            return loadBalances.get(0);
+        }
+        return null;
+    }
+
+    public static Override loadBalanceToOverride(LoadBalance loadBalance) {
+        Override override = new Override();
+        override.setId(loadBalance.getId());
+        override.setHash(loadBalance.getHash());
+        override.setService(loadBalance.getService());
+        override.setEnabled(true);
+        String method = loadBalance.getMethod();
+        String strategy = loadBalance.getStrategy();
+        if (StringUtils.isEmpty(method) || method.equals("*")) {
+            override.setParams("loadbalance=" + strategy);
+        } else {
+            override.setParams(method + ".loadbalance=" + strategy);
+        }
+        return override;
+    }
+
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/RouteRule.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/RouteRule.java
index 43df3f4..c583252 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/RouteRule.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/RouteRule.java
@@ -1,563 +1,696 @@
-///*
-// * 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 org.apache.dubbo.admin.common.util;
-//
-//import org.apache.dubbo.admin.model.domain.ConditionRoute;
-//import org.apache.dubbo.common.utils.StringUtils;
-//
-//import java.text.ParseException;
-//import java.util.*;
-//import java.util.Map.Entry;
-//import java.util.regex.Matcher;
-//import java.util.regex.Pattern;
-//
-///**
-// * Router rule can be divided into two parts, When Condition and Then Condition <br>
-// * When/Then Confition is expressed in a style of (KV) pair, the V part of the condition pair can contain multiple values (a list) <br>
-// * The meaning of Rule: If a request matches When Condition, then use Then Condition to filter providers (only providers match Then Condition will be returned). <br>
-// * The process of using Conditions to match consumers and providers is called `Filter`.
-// * When Condition are used to filter ConsumersController, while Then Condition are used to filter ProvidersController.
-// * RouteRule performs like this: If a Consumer matches When Condition, then only return the ProvidersController matches Then Condition. This means RouteRule should be applied to current Consumer and the providers returned are filtered by RouteRule.<br>
-// *
-// * An example of ConditionRoute Rule:<code>
-// * key1 = value11,value12 & key2 = value21 & key2 != value22 => key3 = value3 & key4 = value41,vlaue42 & key5 !=value51
-// * </code>。
-// * The part before <code>=></code> is called When Condition, it's a KV pair; the follower part is Then Condition, also a KV pair. V part in KV can have more than one value, separated by ','<br><br>
-// *
-// * Value object, thread safe.
-// *
-// */
-//public class RouteRule {
-//    @SuppressWarnings("unchecked")
-//    static RouteRule EMPTY = new RouteRule(Collections.EMPTY_MAP, Collections.EMPTY_MAP);
-//    private static Pattern ROUTE_PATTERN = Pattern.compile("([&!=,]*)\\s*([^&!=,\\s]+)");
-//    private static Pattern CONDITION_SEPERATOR = Pattern.compile("(.*)=>(.*)");
-//    private static Pattern VALUE_LIST_SEPARATOR = Pattern.compile("\\s*,\\s*");
-//    final Map<String, MatchPair> whenCondition;
-//    final Map<String, MatchPair> thenCondition;
-//    private volatile String tostring = null;
-//
-//    // FIXME
-//    private RouteRule(Map<String, MatchPair> when, Map<String, MatchPair> then) {
-//        for (Map.Entry<String, MatchPair> entry : when.entrySet()) {
-//            entry.getValue().freeze();
+/*
+ * 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 org.apache.dubbo.admin.common.util;
+
+import org.apache.dubbo.admin.model.domain.Route;
+import org.apache.dubbo.admin.model.dto.AccessDTO;
+import org.apache.dubbo.admin.model.dto.ConditionRouteDTO;
+import org.apache.dubbo.admin.model.store.BlackWhiteList;
+import org.apache.dubbo.admin.model.store.RoutingRuleDTO;
+import org.apache.dubbo.common.utils.StringUtils;
+
+import java.text.ParseException;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Router rule can be divided into two parts, When Condition and Then Condition <br>
+ * When/Then Confition is expressed in a style of (KV) pair, the V part of the condition pair can contain multiple values (a list) <br>
+ * The meaning of Rule: If a request matches When Condition, then use Then Condition to filter providers (only providers match Then Condition will be returned). <br>
+ * The process of using Conditions to match consumers and providers is called `Filter`.
+ * When Condition are used to filter ConsumersController, while Then Condition are used to filter ProvidersController.
+ * RouteRule performs like this: If a Consumer matches When Condition, then only return the ProvidersController matches Then Condition. This means RouteRule should be applied to current Consumer and the providers returned are filtered by RouteRule.<br>
+ *
+ * An example of ConditionRoute Rule:<code>
+ * key1 = value11,value12 & key2 = value21 & key2 != value22 => key3 = value3 & key4 = value41,vlaue42 & key5 !=value51
+ * </code>。
+ * The part before <code>=></code> is called When Condition, it's a KV pair; the follower part is Then Condition, also a KV pair. V part in KV can have more than one value, separated by ','<br><br>
+ *
+ * Value object, thread safe.
+ *
+ */
+public class RouteRule {
+    @SuppressWarnings("unchecked")
+    static RouteRule EMPTY = new RouteRule(Collections.EMPTY_MAP, Collections.EMPTY_MAP);
+    private static Pattern ROUTE_PATTERN = Pattern.compile("([&!=,]*)\\s*([^&!=,\\s]+)");
+    private static Pattern CONDITION_SEPERATOR = Pattern.compile("(.*)=>(.*)");
+    private static Pattern VALUE_LIST_SEPARATOR = Pattern.compile("\\s*,\\s*");
+    final Map<String, MatchPair> whenCondition;
+    final Map<String, MatchPair> thenCondition;
+    private volatile String tostring = null;
+
+    // FIXME
+    private RouteRule(Map<String, MatchPair> when, Map<String, MatchPair> then) {
+        for (Map.Entry<String, MatchPair> entry : when.entrySet()) {
+            entry.getValue().freeze();
+        }
+        for (Map.Entry<String, MatchPair> entry : then.entrySet()) {
+            entry.getValue().freeze();
+        }
+
+        // NOTE: Both When Condition and Then Condition can be null
+        this.whenCondition = when;
+        this.thenCondition = then;
+    }
+
+    public static Map<String, MatchPair> parseRule(String rule)
+            throws ParseException {
+        Map<String, MatchPair> condition = new HashMap<String, MatchPair>();
+        if (StringUtils.isBlank(rule)) {
+            return condition;
+        }
+        // K-V pair, contains matches part and mismatches part
+        MatchPair pair = null;
+        // V part has multiple values
+        Set<String> values = null;
+        final Matcher matcher = ROUTE_PATTERN.matcher(rule);
+        while (matcher.find()) { // match one by one
+            String separator = matcher.group(1);
+            String content = matcher.group(2);
+            // The expression starts
+            if (separator == null || separator.length() == 0) {
+                pair = new MatchPair();
+                condition.put(content, pair);
+            }
+            // The KV starts
+            else if ("&".equals(separator)) {
+                if (condition.get(content) == null) {
+                    pair = new MatchPair();
+                    condition.put(content, pair);
+                } else {
+                    condition.put(content, pair);
+                }
+
+            }
+            // The Value part of KV starts
+            else if ("=".equals(separator)) {
+                if (pair == null)
+                    throw new ParseException("Illegal route rule \""
+                            + rule + "\", The error char '" + separator
+                            + "' at index " + matcher.start() + " before \""
+                            + content + "\".", matcher.start());
+
+                values = pair.matches;
+                values.add(content);
+            }
+            // The Value part of KV starts
+            else if ("!=".equals(separator)) {
+                if (pair == null)
+                    throw new ParseException("Illegal route rule \""
+                            + rule + "\", The error char '" + separator
+                            + "' at index " + matcher.start() + " before \""
+                            + content + "\".", matcher.start());
+
+                values = pair.unmatches;
+                values.add(content);
+            }
+            // The Value part of KV has multiple values, separated by ','
+            else if (",".equals(separator)) { // separated by ','
+                if (values == null || values.size() == 0)
+                    throw new ParseException("Illegal route rule \""
+                            + rule + "\", The error char '" + separator
+                            + "' at index " + matcher.start() + " before \""
+                            + content + "\".", matcher.start());
+                values.add(content);
+            } else {
+                throw new ParseException("Illegal route rule \"" + rule
+                        + "\", The error char '" + separator + "' at index "
+                        + matcher.start() + " before \"" + content + "\".", matcher.start());
+            }
+        }
+        return condition;
+    }
+
+    /**
+     * Parse the RouteRule as a string into an object.
+     *
+     * @throws ParseException RouteRule string format is wrong. The following input conditions, RouteRule are illegal.
+     * <ul> <li> input is <code>null</code>。
+     * <li> input is "" or " "。
+     * <li> input Rule doesn't have a When Condition
+     * <li> input Rule doesn't have a Then Condition
+     * </ul>
+     */
+    public static RouteRule parse(Route conditionRoute) throws ParseException {
+        if (conditionRoute == null)
+            throw new ParseException("null conditionRoute!", 0);
+
+        if (conditionRoute.getMatchRule() == null && conditionRoute.getFilterRule() == null) {
+            return parse(conditionRoute.getRule());
+        }
+
+        return parse(conditionRoute == null ? null : conditionRoute.getMatchRule(), conditionRoute == null ? null : conditionRoute.getFilterRule());
+    }
+
+    public static RouteRule parse(String whenRule, String thenRule) throws ParseException {
+        /*if (whenRule == null || whenRule.trim().length() == 0) {
+            throw new ParseException("Illegal route rule without when express", 0);
+    	}*/
+        if (thenRule == null || thenRule.trim().length() == 0) {
+            throw new ParseException("Illegal route rule without then express", 0);
+        }
+        Map<String, MatchPair> when = parseRule(whenRule.trim());
+        Map<String, MatchPair> then = parseRule(thenRule.trim());
+        return new RouteRule(when, then);
+    }
+
+    public static RouteRule parse(String rule) throws ParseException {
+        if (StringUtils.isBlank(rule)) {
+            throw new ParseException("Illegal blank route rule", 0);
+        }
+
+        final Matcher matcher = CONDITION_SEPERATOR.matcher(rule);
+        if (!matcher.matches()) throw new ParseException("condition seperator => not found!", 0);
+
+        return parse(matcher.group(1), matcher.group(2));
+    }
+
+    /**
+     * @see #parse(String)
+     * @throws RuntimeException This is an wrapper exception for the {@link ParseException} thrown by the {@link #parse (String)} method.
+     */
+    public static RouteRule parseQuitely(Route conditionRoute) {
+        try {
+            return parse(conditionRoute);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static RoutingRuleDTO insertConditionRule(RoutingRuleDTO existRule, ConditionRouteDTO conditionRoute) {
+        if (existRule == null) {
+            existRule = new RoutingRuleDTO();
+            if (StringUtils.isNotEmpty(conditionRoute.getApplication())) {
+                existRule.setKey(conditionRoute.getApplication());
+                existRule.setScope(Constants.APPLICATION);
+            } else {
+                existRule.setKey(conditionRoute.getService());
+                existRule.setScope(Constants.SERVICE);
+            }
+        }
+        existRule.setConditions(conditionRoute.getConditions());
+        existRule.setDynamic(conditionRoute.isDynamic());
+        existRule.setEnabled(conditionRoute.isEnabled());
+        existRule.setForce(conditionRoute.isForce());
+        existRule.setRuntime(conditionRoute.isRuntime());
+        existRule.setPriority(conditionRoute.getPriority());
+        return existRule;
+    }
+    public static BlackWhiteList convertToBlackWhiteList(AccessDTO accessDTO) {
+        if (accessDTO == null) {
+            return null;
+        }
+        BlackWhiteList blackWhiteList = new BlackWhiteList();
+//        if (StringUtils.isNoneEmpty(accessDTO.getApplication())) {
+//            blackWhiteList.set
 //        }
-//        for (Map.Entry<String, MatchPair> entry : then.entrySet()) {
-//            entry.getValue().freeze();
-//        }
-//
-//        // NOTE: Both When Condition and Then Condition can be null
-//        this.whenCondition = when;
-//        this.thenCondition = then;
-//    }
-//
-//    public static Map<String, MatchPair> parseRule(String rule)
-//            throws ParseException {
-//        Map<String, MatchPair> condition = new HashMap<String, MatchPair>();
-//        if (StringUtils.isBlank(rule)) {
-//            return condition;
-//        }
-//        // K-V pair, contains matches part and mismatches part
-//        MatchPair pair = null;
-//        // V part has multiple values
-//        Set<String> values = null;
-//        final Matcher matcher = ROUTE_PATTERN.matcher(rule);
-//        while (matcher.find()) { // match one by one
-//            String separator = matcher.group(1);
-//            String content = matcher.group(2);
-//            // The expression starts
-//            if (separator == null || separator.length() == 0) {
-//                pair = new MatchPair();
-//                condition.put(content, pair);
-//            }
-//            // The KV starts
-//            else if ("&".equals(separator)) {
-//                if (condition.get(content) == null) {
-//                    pair = new MatchPair();
-//                    condition.put(content, pair);
-//                } else {
-//                    condition.put(content, pair);
-//                }
-//
-//            }
-//            // The Value part of KV starts
-//            else if ("=".equals(separator)) {
-//                if (pair == null)
-//                    throw new ParseException("Illegal route rule \""
-//                            + rule + "\", The error char '" + separator
-//                            + "' at index " + matcher.start() + " before \""
-//                            + content + "\".", matcher.start());
-//
-//                values = pair.matches;
-//                values.add(content);
-//            }
-//            // The Value part of KV starts
-//            else if ("!=".equals(separator)) {
-//                if (pair == null)
-//                    throw new ParseException("Illegal route rule \""
-//                            + rule + "\", The error char '" + separator
-//                            + "' at index " + matcher.start() + " before \""
-//                            + content + "\".", matcher.start());
-//
-//                values = pair.unmatches;
-//                values.add(content);
-//            }
-//            // The Value part of KV has multiple values, separated by ','
-//            else if (",".equals(separator)) { // separated by ','
-//                if (values == null || values.size() == 0)
-//                    throw new ParseException("Illegal route rule \""
-//                            + rule + "\", The error char '" + separator
-//                            + "' at index " + matcher.start() + " before \""
-//                            + content + "\".", matcher.start());
-//                values.add(content);
-//            } else {
-//                throw new ParseException("Illegal route rule \"" + rule
-//                        + "\", The error char '" + separator + "' at index "
-//                        + matcher.start() + " before \"" + content + "\".", matcher.start());
-//            }
-//        }
-//        return condition;
-//    }
-//
-//    /**
-//     * Parse the RouteRule as a string into an object.
-//     *
-//     * @throws ParseException RouteRule string format is wrong. The following input conditions, RouteRule are illegal.
-//     * <ul> <li> input is <code>null</code>。
-//     * <li> input is "" or " "。
-//     * <li> input Rule doesn't have a When Condition
-//     * <li> input Rule doesn't have a Then Condition
-//     * </ul>
-//     */
-//    public static RouteRule parse(ConditionRoute conditionRoute) throws ParseException {
-//        if (conditionRoute == null)
-//            throw new ParseException("null conditionRoute!", 0);
-//
-//        if (conditionRoute.getMatchRule() == null && conditionRoute.getFilterRule() == null) {
-//            return parse(conditionRoute.getRule());
-//        }
-//
-//        return parse(conditionRoute == null ? null : conditionRoute.getMatchRule(), conditionRoute == null ? null : conditionRoute.getFilterRule());
-//    }
-//
-//    public static RouteRule parse(String whenRule, String thenRule) throws ParseException {
-//        /*if (whenRule == null || whenRule.trim().length() == 0) {
-//            throw new ParseException("Illegal route rule without when express", 0);
-//    	}*/
-//        if (thenRule == null || thenRule.trim().length() == 0) {
-//            throw new ParseException("Illegal route rule without then express", 0);
-//        }
-//        Map<String, MatchPair> when = parseRule(whenRule.trim());
-//        Map<String, MatchPair> then = parseRule(thenRule.trim());
-//        return new RouteRule(when, then);
-//    }
-//
-//    public static RouteRule parse(String rule) throws ParseException {
-//        if (StringUtils.isBlank(rule)) {
-//            throw new ParseException("Illegal blank route rule", 0);
-//        }
-//
-//        final Matcher matcher = CONDITION_SEPERATOR.matcher(rule);
-//        if (!matcher.matches()) throw new ParseException("condition seperator => not found!", 0);
-//
-//        return parse(matcher.group(1), matcher.group(2));
-//    }
-//
-//    /**
-//     * @see #parse(String)
-//     * @throws RuntimeException This is an wrapper exception for the {@link ParseException} thrown by the {@link #parse (String)} method.
-//     */
-//    public static RouteRule parseQuitely(ConditionRoute conditionRoute) {
-//        try {
-//            return parse(conditionRoute);
-//        } catch (ParseException e) {
-//            throw new RuntimeException(e);
-//        }
-//    }
-//
-//    static Map<String, MatchPair> parseNameAndValueListString2Condition(Map<String, String> params, Map<String, String> notParams) {
-//        Map<String, MatchPair> condition = new HashMap<String, MatchPair>();
-//
-//        for (Entry<String, String> entry : params.entrySet()) {
-//            String valueListString = entry.getValue();
-//            if (StringUtils.isBlank(valueListString)) {
-//                continue;
-//            }
-//            String[] list = VALUE_LIST_SEPARATOR.split(valueListString);
-//            Set<String> set = new HashSet<String>();
-//            for (String item : list) {
-//                if (StringUtils.isBlank(item)) {
-//                    continue;
-//                }
-//                set.add(item.trim());
-//            }
-//            if (set.isEmpty()) {
-//                continue;
-//            }
-//
-//            String key = entry.getKey();
-//            MatchPair matchPair = condition.get(key);
-//            if (null == matchPair) {
-//                matchPair = new MatchPair();
-//                condition.put(key, matchPair);
-//            }
-//
-//            matchPair.matches = set;
-//        }
-//        for (Entry<String, String> entry : notParams.entrySet()) {
-//            String valueListString = entry.getValue();
-//            if (StringUtils.isBlank(valueListString)) {
-//                continue;
-//            }
-//            String[] list = VALUE_LIST_SEPARATOR.split(valueListString);
-//            Set<String> set = new HashSet<String>();
-//            for (String item : list) {
-//                if (StringUtils.isBlank(item)) {
-//                    continue;
-//                }
-//                set.add(item.trim());
-//            }
-//            if (set.isEmpty()) {
-//                continue;
-//            }
-//
-//            String key = entry.getKey();
-//            MatchPair matchPair = condition.get(key);
-//            if (null == matchPair) {
-//                matchPair = new MatchPair();
-//                condition.put(key, matchPair);
-//            }
-//
-//            matchPair.unmatches = set;
-//        }
-//
-//        return condition;
-//    }
-//
-//    public static RouteRule createFromNameAndValueListString(Map<String, String> whenParams, Map<String, String> notWhenParams,
-//                                                             Map<String, String> thenParams, Map<String, String> notThenParams) {
-//        Map<String, MatchPair> when = parseNameAndValueListString2Condition(whenParams, notWhenParams);
-//        Map<String, MatchPair> then = parseNameAndValueListString2Condition(thenParams, notThenParams);
-//
-//        return new RouteRule(when, then);
-//    }
-//
-//    public static RouteRule createFromCondition(Map<String, MatchPair> whenCondition, Map<String, MatchPair> thenCondition) {
-//        return new RouteRule(whenCondition, thenCondition);
-//    }
-//
-//    public static RouteRule copyWithRemove(RouteRule copy, Set<String> whenParams, Set<String> thenParams) {
-//        Map<String, MatchPair> when = new HashMap<String, MatchPair>();
-//        for (Entry<String, MatchPair> entry : copy.getWhenCondition().entrySet()) {
-//            if (whenParams == null || !whenParams.contains(entry.getKey())) {
-//                when.put(entry.getKey(), entry.getValue());
-//            }
-//        }
-//
-//        Map<String, MatchPair> then = new HashMap<String, MatchPair>();
-//        for (Entry<String, MatchPair> entry : copy.getThenCondition().entrySet()) {
-//            if (thenParams == null || !thenParams.contains(entry.getKey())) {
-//                then.put(entry.getKey(), entry.getValue());
-//            }
-//        }
-//
-//        return new RouteRule(when, then);
-//    }
-//
-//    /**
-//     * Replace with the new condition value.
-//     *
-//     * @param copy Replace Base
-//     * @param whenCondition WhenCondition to replace, if Base does not have an item, insert it directly.
-//     * @param thenCondition ThenCondition to replace, if Base has no items, then insert directly.
-//     * @return RouteRule after replacement
-//     */
-//    public static RouteRule copyWithReplace(RouteRule copy, Map<String, MatchPair> whenCondition, Map<String, MatchPair> thenCondition) {
-//        if (null == copy) {
-//            throw new NullPointerException("Argument copy is null!");
-//        }
-//
-//        Map<String, MatchPair> when = new HashMap<String, MatchPair>();
-//        when.putAll(copy.getWhenCondition());
-//        if (whenCondition != null) {
-//            when.putAll(whenCondition);
-//        }
-//
-//        Map<String, MatchPair> then = new HashMap<String, MatchPair>();
-//        then.putAll(copy.getThenCondition());
-//        if (thenCondition != null) {
-//            then.putAll(thenCondition);
-//        }
-//
-//        return new RouteRule(when, then);
-//    }
-//
-//    // TODO ToString out of the current list is out of order, should we sort?
-//    static void join(StringBuilder sb, Set<String> valueSet) {
-//        boolean isFirst = true;
-//        for (String s : valueSet) {
-//            if (isFirst) {
-//                isFirst = false;
-//            } else {
-//                sb.append(",");
-//            }
-//
-//            sb.append(s);
-//        }
-//    }
-//
-//    /**
-//     * Whether the sample passed the conditions.
-//     * <p>
-//     * If there is a Key in the KV for the sample, there is a corresponding MatchPair, and Value does not pass through MatchPair; {@code false} is returned; otherwise, {@code true} is returned.
-//     *
-//     * @see MatchPair#pass(String)
-//     */
-//    public static boolean matchCondition(Map<String, String> sample,
-//                                         Map<String, MatchPair> condition) {
-//        for (Map.Entry<String, String> entry : sample.entrySet()) {
-//            String key = entry.getKey();
-//
-//            MatchPair pair = condition.get(key);
-//            if (pair != null && !pair.pass(entry.getValue())) {
-//                return false;
-//            }
-//        }
-//        return true;
-//    }
-//
-//
-//    // FIXME Remove such method calls
-//    public static String join(Set<String> valueSet) {
-//        StringBuilder sb = new StringBuilder(128);
-//        join(sb, valueSet);
-//        return sb.toString();
-//    }
-//
-//    // TODO At present, the multiple Key of Condition is in disorder. Should we sort it?
-//    public static void contidionToString(StringBuilder sb, Map<String, MatchPair> condition) {
-//        boolean isFirst = true;
-//        for (Entry<String, MatchPair> entry : condition.entrySet()) {
-//            String keyName = entry.getKey();
-//            MatchPair p = entry.getValue();
-//
-//            @SuppressWarnings("unchecked")
-//            Set<String>[] setArray = new Set[]{p.matches, p.unmatches};
-//            String[] opArray = {" = ", " != "};
-//
-//            for (int i = 0; i < setArray.length; ++i) {
-//                if (setArray[i].isEmpty()) {
-//                    continue;
-//                }
-//                if (isFirst) {
-//                    isFirst = false;
-//                } else {
-//                    sb.append(" & ");
-//                }
-//
-//                sb.append(keyName);
-//                sb.append(opArray[i]);
-//                join(sb, setArray[i]);
-//            }
-//        }
-//    }
-//
-//    public boolean isWhenContainValue(String key, String value) {
-//        MatchPair matchPair = whenCondition.get(key);
-//        if (null == matchPair) {
-//            return false;
-//        }
-//
-//        return matchPair.containeValue(value);
-//    }
-//
-//    public boolean isThenContainValue(String key, String value) {
-//        MatchPair matchPair = thenCondition.get(key);
-//        if (null == matchPair) {
-//            return false;
-//        }
-//
-//        return matchPair.containeValue(value);
-//    }
-//
-//    public boolean isContainValue(String key, String value) {
-//        return isWhenContainValue(key, value) || isThenContainValue(key, value);
-//    }
-//
-//    public Map<String, MatchPair> getWhenCondition() {
-//        return whenCondition;
-//    }
-//
-//    public Map<String, MatchPair> getThenCondition() {
-//        return thenCondition;
-//    }
-//
-//    public String getWhenConditionString() {
-//        StringBuilder sb = new StringBuilder(512);
-//        contidionToString(sb, whenCondition);
-//        return sb.toString();
-//    }
-//
-//    public String getThenConditionString() {
-//        StringBuilder sb = new StringBuilder(512);
-//        contidionToString(sb, thenCondition);
-//        return sb.toString();
-//    }
-//
-//    @Override
-//    public String toString() {
-//        if (tostring != null)
-//            return tostring;
-//        StringBuilder sb = new StringBuilder(512);
-//        contidionToString(sb, whenCondition);
-//        sb.append(" => ");
-//        contidionToString(sb, thenCondition);
-//        return tostring = sb.toString();
-//    }
-//
-//    // Automatic generation with Eclipse
-//    @Override
-//    public int hashCode() {
-//        final int prime = 31;
-//        int result = 1;
-//        result = prime * result + ((thenCondition == null) ? 0 : thenCondition.hashCode());
-//        result = prime * result + ((whenCondition == null) ? 0 : whenCondition.hashCode());
-//        return result;
-//    }
-//
-//    // Automatic generation with Eclipse
-//    @Override
-//    public boolean equals(Object obj) {
-//        if (this == obj)
-//            return true;
-//        if (obj == null)
-//            return false;
-//        if (getClass() != obj.getClass())
-//            return false;
-//        RouteRule other = (RouteRule) obj;
-//        if (thenCondition == null) {
-//            if (other.thenCondition != null)
-//                return false;
-//        } else if (!thenCondition.equals(other.thenCondition))
-//            return false;
-//        if (whenCondition == null) {
-//            if (other.whenCondition != null)
-//                return false;
-//        } else if (!whenCondition.equals(other.whenCondition))
-//            return false;
-//        return true;
-//    }
-//
-//    public static class MatchPair {
-//        Set<String> matches = new HashSet<String>();
-//        Set<String> unmatches = new HashSet<String>();
-//        private volatile boolean freezed = false;
-//
-//        public MatchPair() {
-//        }
-//
-//        public MatchPair(Set<String> matches, Set<String> unmatches) {
-//            if (matches == null || unmatches == null) {
-//                throw new IllegalArgumentException("argument of MatchPair is null!");
-//            }
-//
-//            this.matches = matches;
-//            this.unmatches = unmatches;
-//        }
-//
-//        public Set<String> getMatches() {
-//            return matches;
-//        }
-//
-//        public Set<String> getUnmatches() {
-//            return unmatches;
-//        }
-//
-//        public MatchPair copy() {
-//            MatchPair ret = new MatchPair();
-//            ret.matches.addAll(matches);
-//            ret.unmatches.addAll(unmatches);
-//            return ret;
-//        }
-//
-//        void freeze() {
-//            if (freezed) return;
-//            synchronized (this) {
-//                if (freezed) return;
-//                matches = Collections.unmodifiableSet(matches);
-//                unmatches = Collections.unmodifiableSet(unmatches);
-//            }
-//        }
-//
-//        public boolean containeValue(String value) {
-//            return matches.contains(value) || unmatches.contains(value);
-//        }
-//
-//        /**
-//         * Whether a given value is matched by the {@link MatchPair}.
-//         * return {@code false}, if
-//         * <ol>
-//         * <li>value is in unmatches
-//         * <li>matches is not null, but value is not in matches.
-//         * </ol>
-//         * otherwise, return<code>true</code>。
-//         */
-//        public boolean pass(String sample) {
-//            if (unmatches.contains(sample)) return false;
-//            if (matches.isEmpty()) return true;
-//            return matches.contains(sample);
-//        }
-//
-//        @Override
-//        public String toString() {
-//            return String.format("{matches=%s,unmatches=%s}", matches.toString(), unmatches.toString());
-//        }
-//
-//        // Automatic generation with Eclipse
-//        @Override
-//        public int hashCode() {
-//            final int prime = 31;
-//            int result = 1;
-//            result = prime * result + ((matches == null) ? 0 : matches.hashCode());
-//            result = prime * result + ((unmatches == null) ? 0 : unmatches.hashCode());
-//            return result;
-//        }
-//
-//        // Automatic generation with Eclipse
-//        @Override
-//        public boolean equals(Object obj) {
-//            if (this == obj)
-//                return true;
-//            if (obj == null)
-//                return false;
-//            if (getClass() != obj.getClass())
-//                return false;
-//            MatchPair other = (MatchPair) obj;
-//            if (matches == null) {
-//                if (other.matches != null)
-//                    return false;
-//            } else if (!matches.equals(other.matches))
-//                return false;
-//            if (unmatches == null) {
-//                if (other.unmatches != null)
-//                    return false;
-//            } else if (!unmatches.equals(other.unmatches))
-//                return false;
-//            return true;
-//        }
-//    }
-//}
+//        AccessDTO storeDTO = ConvertUtil.convertDTOtoStore(accessDTO);
+
+        Set<String> whiteList = accessDTO.getWhitelist();
+        Set<String> blackList = accessDTO.getBlacklist();
+        List<String> conditions = new ArrayList<>();
+        if (whiteList != null && whiteList.size() > 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("host != ");
+            for (String white : whiteList) {
+                sb.append(white).append(",");
+            }
+            sb.deleteCharAt(sb.length() - 1);
+            sb.append(" =>");
+            conditions.add(sb.toString());
+        }
+        if (blackList != null && blackList.size() > 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("host = ");
+            for (String black : blackList) {
+                sb.append(black).append(",");
+            }
+            sb.deleteCharAt(sb.length() - 1);
+            sb.append(" =>");
+            conditions.add(sb.toString());
+        }
+        blackWhiteList.setConditions(conditions);
+        return blackWhiteList;
+    }
+
+    public static AccessDTO convertToAccessDTO(BlackWhiteList blackWhiteList, String scope, String key) {
+        if (blackWhiteList == null) {
+            return null;
+        }
+        AccessDTO accessDTO = new AccessDTO();
+        if (scope.equals(Constants.APPLICATION)) {
+            accessDTO.setApplication(key);
+        } else {
+            accessDTO.setService(key);
+        }
+        if (blackWhiteList.getConditions() != null) {
+            for (String condition : blackWhiteList.getConditions()) {
+                if (condition.contains("host != ")) {
+                    //white list
+                    condition = org.apache.commons.lang3.StringUtils.substringBetween(condition, "host !=", " =>").trim();
+                    accessDTO.setWhitelist(new HashSet<>(Arrays.asList(condition.split(","))));
+                }
+                if (condition.contains("host = ")) {
+                    //black list
+                    condition = org.apache.commons.lang3.StringUtils.substringBetween(condition, "host =", " =>").trim();
+                    accessDTO.setBlacklist(new HashSet<>(Arrays.asList(condition.split(","))));
+                }
+            }
+        }
+        return accessDTO;
+    }
+
+    public static Route convertAccessDTOtoRoute(AccessDTO accessDTO) {
+        Route route = new Route();
+        route.setService(accessDTO.getService());
+        route.setForce(true);
+        route.setFilterRule("false");
+        route.setEnabled(true);
+
+        Map<String, RouteRule.MatchPair> when = new HashMap<>();
+        RouteRule.MatchPair matchPair = new RouteRule.MatchPair(new HashSet<>(), new HashSet<>());
+        when.put(Route.KEY_CONSUMER_HOST, matchPair);
+
+        if (accessDTO.getWhitelist() != null) {
+            matchPair.getUnmatches().addAll(accessDTO.getWhitelist());
+        }
+        if (accessDTO.getBlacklist() != null) {
+            matchPair.getMatches().addAll(accessDTO.getBlacklist());
+        }
+
+        StringBuilder sb = new StringBuilder();
+        RouteRule.contidionToString(sb, when);
+        route.setMatchRule(sb.toString());
+        return route;
+    }
+
+    public static ConditionRouteDTO createConditionRouteFromRule(RoutingRuleDTO routingRuleDTO) {
+        ConditionRouteDTO conditionRouteDTO = new ConditionRouteDTO();
+        if (routingRuleDTO.getScope().equals(Constants.SERVICE)) {
+            conditionRouteDTO.setService(routingRuleDTO.getKey());
+        } else {
+            conditionRouteDTO.setApplication(routingRuleDTO.getKey());
+        }
+        conditionRouteDTO.setConditions(routingRuleDTO.getConditions());
+        conditionRouteDTO.setPriority(routingRuleDTO.getPriority());
+        conditionRouteDTO.setEnabled(routingRuleDTO.isEnabled());
+        conditionRouteDTO.setForce(routingRuleDTO.isForce());
+        conditionRouteDTO.setRuntime(routingRuleDTO.isRuntime());
+        conditionRouteDTO.setDynamic(routingRuleDTO.isDynamic());
+        return conditionRouteDTO;
+    }
+
+    public static Route convertBlackWhiteListtoRoute(BlackWhiteList blackWhiteList, String scope, String key) {
+        AccessDTO accessDTO = convertToAccessDTO(blackWhiteList, scope, key);
+        return convertAccessDTOtoRoute(accessDTO);
+    }
+
+    static Map<String, MatchPair> parseNameAndValueListString2Condition(Map<String, String> params, Map<String, String> notParams) {
+        Map<String, MatchPair> condition = new HashMap<String, MatchPair>();
+
+        for (Entry<String, String> entry : params.entrySet()) {
+            String valueListString = entry.getValue();
+            if (StringUtils.isBlank(valueListString)) {
+                continue;
+            }
+            String[] list = VALUE_LIST_SEPARATOR.split(valueListString);
+            Set<String> set = new HashSet<String>();
+            for (String item : list) {
+                if (StringUtils.isBlank(item)) {
+                    continue;
+                }
+                set.add(item.trim());
+            }
+            if (set.isEmpty()) {
+                continue;
+            }
+
+            String key = entry.getKey();
+            MatchPair matchPair = condition.get(key);
+            if (null == matchPair) {
+                matchPair = new MatchPair();
+                condition.put(key, matchPair);
+            }
+
+            matchPair.matches = set;
+        }
+        for (Entry<String, String> entry : notParams.entrySet()) {
+            String valueListString = entry.getValue();
+            if (StringUtils.isBlank(valueListString)) {
+                continue;
+            }
+            String[] list = VALUE_LIST_SEPARATOR.split(valueListString);
+            Set<String> set = new HashSet<String>();
+            for (String item : list) {
+                if (StringUtils.isBlank(item)) {
+                    continue;
+                }
+                set.add(item.trim());
+            }
+            if (set.isEmpty()) {
+                continue;
+            }
+
+            String key = entry.getKey();
+            MatchPair matchPair = condition.get(key);
+            if (null == matchPair) {
+                matchPair = new MatchPair();
+                condition.put(key, matchPair);
+            }
+
+            matchPair.unmatches = set;
+        }
+
+        return condition;
+    }
+
+    public static RouteRule createFromNameAndValueListString(Map<String, String> whenParams, Map<String, String> notWhenParams,
+                                                             Map<String, String> thenParams, Map<String, String> notThenParams) {
+        Map<String, MatchPair> when = parseNameAndValueListString2Condition(whenParams, notWhenParams);
+        Map<String, MatchPair> then = parseNameAndValueListString2Condition(thenParams, notThenParams);
+
+        return new RouteRule(when, then);
+    }
+
+    public static RouteRule createFromCondition(Map<String, MatchPair> whenCondition, Map<String, MatchPair> thenCondition) {
+        return new RouteRule(whenCondition, thenCondition);
+    }
+
+    public static RouteRule copyWithRemove(RouteRule copy, Set<String> whenParams, Set<String> thenParams) {
+        Map<String, MatchPair> when = new HashMap<String, MatchPair>();
+        for (Entry<String, MatchPair> entry : copy.getWhenCondition().entrySet()) {
+            if (whenParams == null || !whenParams.contains(entry.getKey())) {
+                when.put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        Map<String, MatchPair> then = new HashMap<String, MatchPair>();
+        for (Entry<String, MatchPair> entry : copy.getThenCondition().entrySet()) {
+            if (thenParams == null || !thenParams.contains(entry.getKey())) {
+                then.put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        return new RouteRule(when, then);
+    }
+
+    /**
+     * Replace with the new condition value.
+     *
+     * @param copy Replace Base
+     * @param whenCondition WhenCondition to replace, if Base does not have an item, insert it directly.
+     * @param thenCondition ThenCondition to replace, if Base has no items, then insert directly.
+     * @return RouteRule after replacement
+     */
+    public static RouteRule copyWithReplace(RouteRule copy, Map<String, MatchPair> whenCondition, Map<String, MatchPair> thenCondition) {
+        if (null == copy) {
+            throw new NullPointerException("Argument copy is null!");
+        }
+
+        Map<String, MatchPair> when = new HashMap<String, MatchPair>();
+        when.putAll(copy.getWhenCondition());
+        if (whenCondition != null) {
+            when.putAll(whenCondition);
+        }
+
+        Map<String, MatchPair> then = new HashMap<String, MatchPair>();
+        then.putAll(copy.getThenCondition());
+        if (thenCondition != null) {
+            then.putAll(thenCondition);
+        }
+
+        return new RouteRule(when, then);
+    }
+
+    // TODO ToString out of the current list is out of order, should we sort?
+    static void join(StringBuilder sb, Set<String> valueSet) {
+        boolean isFirst = true;
+        for (String s : valueSet) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                sb.append(",");
+            }
+
+            sb.append(s);
+        }
+    }
+
+    /**
+     * Whether the sample passed the conditions.
+     * <p>
+     * If there is a Key in the KV for the sample, there is a corresponding MatchPair, and Value does not pass through MatchPair; {@code false} is returned; otherwise, {@code true} is returned.
+     *
+     * @see MatchPair#pass(String)
+     */
+    public static boolean matchCondition(Map<String, String> sample,
+                                         Map<String, MatchPair> condition) {
+        for (Map.Entry<String, String> entry : sample.entrySet()) {
+            String key = entry.getKey();
+
+            MatchPair pair = condition.get(key);
+            if (pair != null && !pair.pass(entry.getValue())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    // FIXME Remove such method calls
+    public static String join(Set<String> valueSet) {
+        StringBuilder sb = new StringBuilder(128);
+        join(sb, valueSet);
+        return sb.toString();
+    }
+
+    // TODO At present, the multiple Key of Condition is in disorder. Should we sort it?
+    public static void contidionToString(StringBuilder sb, Map<String, MatchPair> condition) {
+        boolean isFirst = true;
+        for (Entry<String, MatchPair> entry : condition.entrySet()) {
+            String keyName = entry.getKey();
+            MatchPair p = entry.getValue();
+
+            @SuppressWarnings("unchecked")
+            Set<String>[] setArray = new Set[]{p.matches, p.unmatches};
+            String[] opArray = {" = ", " != "};
+
+            for (int i = 0; i < setArray.length; ++i) {
+                if (setArray[i].isEmpty()) {
+                    continue;
+                }
+                if (isFirst) {
+                    isFirst = false;
+                } else {
+                    sb.append(" & ");
+                }
+
+                sb.append(keyName);
+                sb.append(opArray[i]);
+                join(sb, setArray[i]);
+            }
+        }
+    }
+
+
+    public boolean isWhenContainValue(String key, String value) {
+        MatchPair matchPair = whenCondition.get(key);
+        if (null == matchPair) {
+            return false;
+        }
+
+        return matchPair.containeValue(value);
+    }
+
+    public boolean isThenContainValue(String key, String value) {
+        MatchPair matchPair = thenCondition.get(key);
+        if (null == matchPair) {
+            return false;
+        }
+
+        return matchPair.containeValue(value);
+    }
+
+    public boolean isContainValue(String key, String value) {
+        return isWhenContainValue(key, value) || isThenContainValue(key, value);
+    }
+
+    public Map<String, MatchPair> getWhenCondition() {
+        return whenCondition;
+    }
+
+    public Map<String, MatchPair> getThenCondition() {
+        return thenCondition;
+    }
+
+    public String getWhenConditionString() {
+        StringBuilder sb = new StringBuilder(512);
+        contidionToString(sb, whenCondition);
+        return sb.toString();
+    }
+
+    public String getThenConditionString() {
+        StringBuilder sb = new StringBuilder(512);
+        contidionToString(sb, thenCondition);
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        if (tostring != null)
+            return tostring;
+        StringBuilder sb = new StringBuilder(512);
+        contidionToString(sb, whenCondition);
+        sb.append(" => ");
+        contidionToString(sb, thenCondition);
+        return tostring = sb.toString();
+    }
+
+    // Automatic generation with Eclipse
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((thenCondition == null) ? 0 : thenCondition.hashCode());
+        result = prime * result + ((whenCondition == null) ? 0 : whenCondition.hashCode());
+        return result;
+    }
+
+    // Automatic generation with Eclipse
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        RouteRule other = (RouteRule) obj;
+        if (thenCondition == null) {
+            if (other.thenCondition != null)
+                return false;
+        } else if (!thenCondition.equals(other.thenCondition))
+            return false;
+        if (whenCondition == null) {
+            if (other.whenCondition != null)
+                return false;
+        } else if (!whenCondition.equals(other.whenCondition))
+            return false;
+        return true;
+    }
+
+    public static class MatchPair {
+        Set<String> matches = new HashSet<String>();
+        Set<String> unmatches = new HashSet<String>();
+        private volatile boolean freezed = false;
+
+        public MatchPair() {
+        }
+
+        public MatchPair(Set<String> matches, Set<String> unmatches) {
+            if (matches == null || unmatches == null) {
+                throw new IllegalArgumentException("argument of MatchPair is null!");
+            }
+
+            this.matches = matches;
+            this.unmatches = unmatches;
+        }
+
+        public Set<String> getMatches() {
+            return matches;
+        }
+
+        public Set<String> getUnmatches() {
+            return unmatches;
+        }
+
+        public MatchPair copy() {
+            MatchPair ret = new MatchPair();
+            ret.matches.addAll(matches);
+            ret.unmatches.addAll(unmatches);
+            return ret;
+        }
+
+        void freeze() {
+            if (freezed) return;
+            synchronized (this) {
+                if (freezed) return;
+                matches = Collections.unmodifiableSet(matches);
+                unmatches = Collections.unmodifiableSet(unmatches);
+            }
+        }
+
+        public boolean containeValue(String value) {
+            return matches.contains(value) || unmatches.contains(value);
+        }
+
+        /**
+         * Whether a given value is matched by the {@link MatchPair}.
+         * return {@code false}, if
+         * <ol>
+         * <li>value is in unmatches
+         * <li>matches is not null, but value is not in matches.
+         * </ol>
+         * otherwise, return<code>true</code>。
+         */
+        public boolean pass(String sample) {
+            if (unmatches.contains(sample)) return false;
+            if (matches.isEmpty()) return true;
+            return matches.contains(sample);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("{matches=%s,unmatches=%s}", matches.toString(), unmatches.toString());
+        }
+
+        // Automatic generation with Eclipse
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((matches == null) ? 0 : matches.hashCode());
+            result = prime * result + ((unmatches == null) ? 0 : unmatches.hashCode());
+            return result;
+        }
+
+        // Automatic generation with Eclipse
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            MatchPair other = (MatchPair) obj;
+            if (matches == null) {
+                if (other.matches != null)
+                    return false;
+            } else if (!matches.equals(other.matches))
+                return false;
+            if (unmatches == null) {
+                if (other.unmatches != null)
+                    return false;
+            } else if (!unmatches.equals(other.unmatches))
+                return false;
+            return true;
+        }
+    }
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/AccessesController.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/AccessesController.java
index 276ebbf..25ca33f 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/AccessesController.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/AccessesController.java
@@ -1,165 +1,114 @@
-///*
-// * 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 org.apache.dubbo.admin.controller;
-//
-//import org.apache.dubbo.common.logger.Logger;
-//import org.apache.dubbo.common.logger.LoggerFactory;
-//import org.apache.commons.lang3.StringUtils;
-//import org.apache.dubbo.admin.common.exception.ParamValidationException;
-//import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
-//import org.apache.dubbo.admin.model.dto.AccessDTO;
-//import org.apache.dubbo.admin.service.RouteService;
-//import org.apache.dubbo.admin.model.domain.ConditionRoute;
-//import org.apache.dubbo.admin.common.util.RouteRule;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.http.HttpStatus;
-//import org.springframework.web.bind.annotation.*;
-//
-//import java.text.ParseException;
-//import java.util.*;
-//
-//@RestController
-//@RequestMapping("/api/{env}/rules/access")
-//public class AccessesController {
-//    private static final Logger logger = LoggerFactory.getLogger(AccessesController.class);
-//
-//    private final RouteService routeService;
-//
-//    @Autowired
-//    public AccessesController(RouteService routeService) {
-//        this.routeService = routeService;
+/*
+ * 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 org.apache.dubbo.admin.controller;
+
+import org.apache.dubbo.admin.common.util.RouteRule;
+import org.apache.dubbo.admin.model.dto.ConditionRouteDTO;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.dubbo.admin.common.exception.ParamValidationException;
+import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
+import org.apache.dubbo.admin.model.dto.AccessDTO;
+import org.apache.dubbo.admin.service.RouteService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.ParseException;
+import java.util.*;
+
+@RestController
+@RequestMapping("/api/{env}/rules/access")
+public class AccessesController {
+    private static final Logger logger = LoggerFactory.getLogger(AccessesController.class);
+
+    private final RouteService routeService;
+
+    @Autowired
+    public AccessesController(RouteService routeService) {
+        this.routeService = routeService;
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    public List<AccessDTO> searchAccess(@RequestParam(required = false) String serviceName,
+                                        @RequestParam(required = false) String application,
+                                        @PathVariable String env) throws ParseException {
+        if (StringUtils.isBlank(serviceName) && StringUtils.isBlank(application)) {
+            throw new ParamValidationException("Either service or application is required");
+        }
+        List<AccessDTO> accessDTOS = new ArrayList<>();
+        AccessDTO accessDTO;
+        if (StringUtils.isNotBlank(application)) {
+            accessDTO = routeService.findAccess(application);
+        } else {
+            accessDTO = routeService.findAccess(serviceName);
+        }
+        if (accessDTO != null) {
+            accessDTO.setEnabled(true);
+            accessDTOS.add(accessDTO);
+        }
+        return accessDTOS;
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public AccessDTO detailAccess(@PathVariable String id, @PathVariable String env) throws ParseException {
+        AccessDTO accessDTO = routeService.findAccess(id);
+        return accessDTO;
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public void deleteAccess(@PathVariable String id, @PathVariable String env) {
+        routeService.deleteAccess(id);
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    @ResponseStatus(HttpStatus.CREATED)
+    public void createAccess(@RequestBody AccessDTO accessDTO, @PathVariable String env) {
+        if (StringUtils.isBlank(accessDTO.getService()) && StringUtils.isBlank(accessDTO.getApplication())) {
+            throw new ParamValidationException("Either Service or application is required.");
+        }
+        if (accessDTO.getBlacklist() == null && accessDTO.getWhitelist() == null) {
+            throw new ParamValidationException("One of Blacklist/Whitelist is required.");
+        }
+        routeService.createAccess(accessDTO);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+    public void updateAccess(@PathVariable String id, @RequestBody AccessDTO accessDTO, @PathVariable String env) {
+
+        ConditionRouteDTO route = routeService.findConditionRoute(id);
+        if (Objects.isNull(route)) {
+            throw new ResourceNotFoundException("Unknown ID!");
+        }
+        routeService.updateAccess(accessDTO);
+    }
+
+//    private ConditionRouteDTO routeCopy(ConditionRouteDTO old) {
+//        ConditionRouteDTO newRoute = new ConditionRouteDTO();
+//        newRoute.setKey(old.getKey());
+//        newRoute.setScope(old.getScope());
+//        newRoute.setConditions(old.getConditions());
+//        newRoute.setRuntime(old.isRuntime());
+//        newRoute.setEnabled(old.isEnabled());
+//        newRoute.setDynamic(old.isDynamic());
+//        newRoute.setForce(old.isForce());
+//        newRoute.setPriority(old.getPriority());
+//        newRoute.setBlackWhiteList(null);
+//        return newRoute;
 //    }
-//
-//    @RequestMapping(method = RequestMethod.GET)
-//    public List<AccessDTO> searchAccess(@RequestParam(required = false) String service,
-//                                        @RequestParam(required = false) String application,
-//                                        @PathVariable String env) throws ParseException {
-//        List<AccessDTO> result = new ArrayList<>();
-//        List<ConditionRoute> routes = new ArrayList<>();
-//        if (StringUtils.isNotBlank(service)) {
-//            ConditionRoute route = routeService.getBlackwhitelistRouteByService(service.trim());
-//            if (route != null) {
-//                routes.add(route);
-//            }
-//        } else if (StringUtils.isNotBlank(application)) {
-//            ConditionRoute route = routeService.getBlackwhitelistRouteByService()
-//        }
-//
-//        for (ConditionRoute route : routes) {
-//            // Match WhiteBlackList ConditionRoute
-//            if (route.getName().endsWith(AccessDTO.KEY_BLACK_WHITE_LIST)) {
-//                AccessDTO accessDTO = new AccessDTO();
-//                accessDTO.setId(route.getHash());
-//                accessDTO.setService(route.getService());
-//                Map<String, RouteRule.MatchPair> when = RouteRule.parseRule(route.getMatchRule());
-//                for (String key : when.keySet()) {
-//                    accessDTO.setWhitelist(when.get(key).getUnmatches());
-//                    accessDTO.setBlacklist(when.get(key).getMatches());
-//                }
-//                result.add(accessDTO);
-//            }
-//        }
-//        return result;
-//    }
-//
-//    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
-//    public AccessDTO detailAccess(@PathVariable String id, @PathVariable String env) throws ParseException {
-//        ConditionRoute route = routeService.findRoute(id);
-//        if (route.getName().endsWith(AccessDTO.KEY_BLACK_WHITE_LIST)) {
-//            AccessDTO accessDTO = new AccessDTO();
-//            accessDTO.setId(route.getHash());
-//            accessDTO.setService(route.getService());
-//            Map<String, RouteRule.MatchPair> when = RouteRule.parseRule(route.getMatchRule());
-//            for (String key : when.keySet()) {
-//                accessDTO.setWhitelist(when.get(key).getUnmatches());
-//                accessDTO.setBlacklist(when.get(key).getMatches());
-//            }
-//            return accessDTO;
-//        } else {
-//            return null;
-//        }
-//    }
-//
-//    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
-//    public void deleteAccess(@PathVariable String id, @PathVariable String env) {
-//        routeService.deleteRoute(id);
-//    }
-//
-//    @RequestMapping(method = RequestMethod.POST)
-//    @ResponseStatus(HttpStatus.CREATED)
-//    public void createAccess(@RequestBody AccessDTO accessDTO, @PathVariable String env) {
-//        if (StringUtils.isBlank(accessDTO.getService())) {
-//            throw new ParamValidationException("Service is required.");
-//        }
-//        if (accessDTO.getBlacklist() == null && accessDTO.getWhitelist() == null) {
-//            throw new ParamValidationException("One of Blacklist/Whitelist is required.");
-//        }
-//
-//        ConditionRoute route = routeService.getBlackwhitelistRouteByService(accessDTO.getService());
-//
-//        if (route != null) {
-//            throw new ParamValidationException(accessDTO.getService() + " is existed.");
-//        }
-//
-//        route = new ConditionRoute();
-//        route.setService(accessDTO.getService());
-//        route.setForce(true);
-//        route.setName(accessDTO.getService() + " " + AccessDTO.KEY_BLACK_WHITE_LIST);
-//        route.setFilterRule("false");
-//        route.setEnabled(true);
-//
-//        Map<String, RouteRule.MatchPair> when = new HashMap<>();
-//        RouteRule.MatchPair matchPair = new RouteRule.MatchPair(new HashSet<>(), new HashSet<>());
-//        when.put(ConditionRoute.KEY_CONSUMER_HOST, matchPair);
-//
-//        if (accessDTO.getWhitelist() != null) {
-//            matchPair.getUnmatches().addAll(accessDTO.getWhitelist());
-//        }
-//        if (accessDTO.getBlacklist() != null) {
-//            matchPair.getMatches().addAll(accessDTO.getBlacklist());
-//        }
-//
-//        StringBuilder sb = new StringBuilder();
-//        RouteRule.contidionToString(sb, when);
-//        route.setMatchRule(sb.toString());
-//        routeService.createRoute(route);
-//    }
-//
-//    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
-//    public void updateAccess(@PathVariable String id, @RequestBody AccessDTO accessDTO, @PathVariable String env) {
-//        ConditionRoute route = routeService.findRoute(id);
-//        if (Objects.isNull(route)) {
-//            throw new ResourceNotFoundException("Unknown ID!");
-//        }
-//        Map<String, RouteRule.MatchPair> when = new HashMap<>();
-//        RouteRule.MatchPair matchPair = new RouteRule.MatchPair(new HashSet<>(), new HashSet<>());
-//        when.put(ConditionRoute.KEY_CONSUMER_HOST, matchPair);
-//
-//        if (accessDTO.getWhitelist() != null) {
-//            matchPair.getUnmatches().addAll(accessDTO.getWhitelist());
-//        }
-//        if (accessDTO.getBlacklist() != null) {
-//            matchPair.getMatches().addAll(accessDTO.getBlacklist());
-//        }
-//
-//        StringBuilder sb = new StringBuilder();
-//        RouteRule.contidionToString(sb, when);
-//        route.setMatchRule(sb.toString());
-//
-//        routeService.updateRoute(route);
-//    }
-//}
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/ConditionRoutesController.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/ConditionRoutesController.java
index c5ca576..5038ed0 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/ConditionRoutesController.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/ConditionRoutesController.java
@@ -65,7 +65,7 @@
         if (oldConditionRoute == null) {
             throw new ResourceNotFoundException("can not find route rule for: " + id);
         }
-        routeService.updateConditionRoute(oldConditionRoute, newConditionRoute);
+        routeService.updateConditionRoute(newConditionRoute);
         return true;
     }
 
@@ -80,8 +80,7 @@
         if (StringUtils.isNotEmpty(serviceName)) {
             conditionRoute = routeService.findConditionRoute(serviceName);
         }
-        if (conditionRoute != null) {
-            conditionRoute = convertRouteDTOtoDisplay(conditionRoute);
+        if (conditionRoute != null && conditionRoute.getConditions() != null) {
             result.add(conditionRoute);
         }
         return result;
@@ -90,10 +89,9 @@
     @RequestMapping(value = "/{id}", method = RequestMethod.GET)
     public ConditionRouteDTO detailRoute(@PathVariable String id, @PathVariable String env) {
         ConditionRouteDTO conditionRoute = routeService.findConditionRoute(id);
-        if (conditionRoute == null) {
+        if (conditionRoute == null || conditionRoute.getConditions() == null) {
             throw new ResourceNotFoundException("Unknown ID!");
         }
-        conditionRoute = convertRouteDTOtoDisplay(conditionRoute);
         return conditionRoute;
     }
 
@@ -115,14 +113,4 @@
         return true;
     }
 
-    private ConditionRouteDTO convertRouteDTOtoDisplay(ConditionRouteDTO conditionRouteDTO) {
-        if (conditionRouteDTO.getScope().equals("application")) {
-            conditionRouteDTO.setApplication(conditionRouteDTO.getKey());
-        } else {
-            conditionRouteDTO.setService(conditionRouteDTO.getKey());
-        }
-        conditionRouteDTO.setScope(null);
-        conditionRouteDTO.setKey(null);
-        return conditionRouteDTO;
-    }
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/LoadBalanceController.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/LoadBalanceController.java
index 590e6ef..bc130e5 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/LoadBalanceController.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/LoadBalanceController.java
@@ -1,53 +1,53 @@
-///*
-// * 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 org.apache.dubbo.admin.controller;
-//
-//import org.apache.commons.lang3.StringUtils;
-//import org.apache.dubbo.admin.common.exception.ParamValidationException;
-//import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
-//import org.apache.dubbo.admin.model.dto.BalancingDTO;
-//import org.apache.dubbo.admin.service.OverrideService;
-//import org.apache.dubbo.admin.model.domain.LoadBalance;
-//import org.apache.dubbo.admin.model.domain.Override;
-//import org.apache.dubbo.admin.common.util.OverrideUtils;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.http.HttpStatus;
-//import org.springframework.web.bind.annotation.*;
-//
-//import java.util.ArrayList;
-//import java.util.List;
-//
-//import static org.apache.dubbo.admin.common.util.OverrideUtils.overrideToLoadBalance;
-//
-//@RestController
-//@RequestMapping("/api/{env}/rules/balancing")
-//public class LoadBalanceController {
-//
-//    private final OverrideService overrideService;
-//
-//    @Autowired
-//    public LoadBalanceController(OverrideService overrideService) {
-//        this.overrideService = overrideService;
-//    }
-//
-//    @RequestMapping(method = RequestMethod.POST)
-//    @ResponseStatus(HttpStatus.CREATED)
-//    public boolean createLoadbalance(@RequestBody BalancingDTO balancingDTO, @PathVariable String env) throws ParamValidationException {
+/*
+ * 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 org.apache.dubbo.admin.controller;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.dubbo.admin.common.exception.ParamValidationException;
+import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
+import org.apache.dubbo.admin.model.dto.BalancingDTO;
+import org.apache.dubbo.admin.service.OverrideService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+@RestController
+@RequestMapping("/api/{env}/rules/balancing")
+public class LoadBalanceController {
+
+    private final OverrideService overrideService;
+
+    @Autowired
+    public LoadBalanceController(OverrideService overrideService) {
+        this.overrideService = overrideService;
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    @ResponseStatus(HttpStatus.CREATED)
+    public boolean createLoadbalance(@RequestBody BalancingDTO balancingDTO, @PathVariable String env) throws ParamValidationException {
+        if (StringUtils.isBlank(balancingDTO.getService()) && StringUtils.isBlank(balancingDTO.getApplication())) {
+            throw new ParamValidationException("Either Service or application is required.");
+        }
+        overrideService.saveBalance(balancingDTO);
 //        String serviceName = balancingDTO.getService();
 //        if (StringUtils.isEmpty(serviceName)) {
 //            throw new ParamValidationException("serviceName is Empty!");
@@ -57,11 +57,18 @@
 //        loadBalance.setMethod(formatMethodName(balancingDTO.getMethodName()));
 //        loadBalance.setStrategy(balancingDTO.getStrategy());
 //        overrideService.saveOverride(OverrideUtils.loadBalanceToOverride(loadBalance));
-//        return true;
-//    }
-//
-//    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
-//    public boolean updateLoadbalance(@PathVariable String id, @RequestBody BalancingDTO balancingDTO, @PathVariable String env) throws ParamValidationException {
+        return true;
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+    public boolean updateLoadbalance(@PathVariable String id, @RequestBody BalancingDTO balancingDTO, @PathVariable String env) throws ParamValidationException {
+        if (id == null) {
+            throw new ParamValidationException("Unknown ID!");
+        }
+        BalancingDTO balancing = overrideService.findBalance(id);
+        if (balancing == null) {
+            throw new ResourceNotFoundException("Unknown ID!");
+        }
 //        Override override = overrideService.findById(id);
 //        if (override == null) {
 //            throw new ResourceNotFoundException("Unknown ID!");
@@ -73,62 +80,54 @@
 //        loadBalance.setService(old.getService());
 //        loadBalance.setHash(id);
 //        overrideService.updateOverride(OverrideUtils.loadBalanceToOverride(loadBalance));
-//        return true;
-//    }
-//
-//    @RequestMapping(method = RequestMethod.GET)
-//    public List<BalancingDTO> searchLoadbalances(@RequestParam(required = false) String service, @PathVariable String env) {
-//        List<Override> overrides;
-//        if (StringUtils.isEmpty(service)) {
-//            overrides = overrideService.findAll();
-//        } else {
-//            overrides = overrideService.findByService(service);
-//        }
-//        List<BalancingDTO> loadBalances = new ArrayList<>();
-//        if (overrides != null) {
-//            for (Override override : overrides) {
-//                LoadBalance l = overrideToLoadBalance(override);
-//                if (l != null) {
-//                    BalancingDTO balancingDTO = new BalancingDTO();
-//                    balancingDTO.setService(l.getService());
-//                    balancingDTO.setMethodName(l.getMethod());
-//                    balancingDTO.setStrategy(l.getStrategy());
-//                    balancingDTO.setId(l.getHash());
-//                    loadBalances.add(balancingDTO);
-//                }
-//            }
-//        }
-//        return loadBalances;
-//    }
-//
-//    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
-//    public BalancingDTO detailLoadBalance(@PathVariable String id, @PathVariable String env) throws ParamValidationException {
-//        Override override = overrideService.findById(id);
-//        if (override == null) {
-//            throw new ResourceNotFoundException("Unknown ID!");
-//        }
-//
+        overrideService.saveBalance(balancingDTO);
+        return true;
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    public List<BalancingDTO> searchLoadbalances(@RequestParam(required = false) String serviceName,
+                                                 @RequestParam(required = false) String application,
+                                                 @PathVariable String env) {
+
+        if (StringUtils.isBlank(serviceName) && StringUtils.isBlank(application)) {
+            throw new ParamValidationException("Either service or application is required");
+        }
+        BalancingDTO balancingDTO;
+        if (StringUtils.isNotBlank(application)) {
+            balancingDTO = overrideService.findBalance(application);
+        } else {
+            balancingDTO = overrideService.findBalance(serviceName);
+        }
+        List<BalancingDTO> balancingDTOS = new ArrayList<>();
+        if (balancingDTO != null) {
+            balancingDTOS.add(balancingDTO);
+        }
+        return balancingDTOS;
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public BalancingDTO detailLoadBalance(@PathVariable String id, @PathVariable String env) throws ParamValidationException {
+        BalancingDTO balancingDTO = overrideService.findBalance(id);
+        if (balancingDTO == null) {
+            throw new ResourceNotFoundException("Unknown ID!");
+        }
+        return balancingDTO;
+
 //        LoadBalance loadBalance = OverrideUtils.overrideToLoadBalance(override);
 //        BalancingDTO balancingDTO = new BalancingDTO();
 //        balancingDTO.setService(loadBalance.getService());
 //        balancingDTO.setMethodName(loadBalance.getMethod());
 //        balancingDTO.setStrategy(loadBalance.getStrategy());
-//        return balancingDTO;
-//    }
-//
-//    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
-//    public boolean deleteLoadBalance(@PathVariable String id, @PathVariable String env) {
-//        if (id == null) {
-//            throw new IllegalArgumentException("Argument of id is null!");
-//        }
-//        overrideService.deleteOverride(id);
-//        return true;
-//    }
-//
-//    private String formatMethodName(String method) {
-//        if (method.equals("0")) {
-//            return "*";
-//        }
-//        return method;
-//    }
-//}
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public boolean deleteLoadBalance(@PathVariable String id, @PathVariable String env) {
+        if (id == null) {
+            throw new IllegalArgumentException("Argument of id is null!");
+        }
+        overrideService.deleteBalance(id);
+        return true;
+    }
+
+
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/OverridesController.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/OverridesController.java
index ac0eb6e..b94d659 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/OverridesController.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/OverridesController.java
@@ -21,7 +21,7 @@
 import org.apache.dubbo.admin.common.exception.ParamValidationException;
 import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
 import org.apache.dubbo.admin.common.exception.VersionValidationException;
-import org.apache.dubbo.admin.model.dto.OverrideDTO;
+import org.apache.dubbo.admin.model.dto.DynamicConfigDTO;
 import org.apache.dubbo.admin.service.OverrideService;
 import org.apache.dubbo.admin.service.ProviderService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,7 +46,7 @@
 
     @RequestMapping(method = RequestMethod.POST)
     @ResponseStatus(HttpStatus.CREATED)
-    public boolean createOverride(@RequestBody OverrideDTO overrideDTO, @PathVariable String env) {
+    public boolean createOverride(@RequestBody DynamicConfigDTO overrideDTO, @PathVariable String env) {
         String serviceName = overrideDTO.getService();
         String application = overrideDTO.getApplication();
         if (StringUtils.isEmpty(serviceName) && StringUtils.isEmpty(application)) {
@@ -60,41 +60,39 @@
     }
 
     @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
-    public boolean updateOverride(@PathVariable String id, @RequestBody OverrideDTO overrideDTO, @PathVariable String env) {
-        OverrideDTO old = overrideService.findOverride(id);
+    public boolean updateOverride(@PathVariable String id, @RequestBody DynamicConfigDTO overrideDTO, @PathVariable String env) {
+        DynamicConfigDTO old = overrideService.findOverride(id);
         if (old == null) {
             throw new ResourceNotFoundException("Unknown ID!");
         }
-        overrideService.updateOverride(old, overrideDTO);
+        overrideService.updateOverride(overrideDTO);
         return true;
     }
 
     @RequestMapping(method = RequestMethod.GET)
-    public List<OverrideDTO> searchOverride(@RequestParam(required = false) String serviceName,
-                                            @RequestParam(required = false) String application,
-                                            @PathVariable String env) {
-        OverrideDTO override = null;
-        List<OverrideDTO> result = new ArrayList<>();
+    public List<DynamicConfigDTO> searchOverride(@RequestParam(required = false) String serviceName,
+                                                 @RequestParam(required = false) String application,
+                                                 @PathVariable String env) {
+        DynamicConfigDTO override = null;
+        List<DynamicConfigDTO> result = new ArrayList<>();
         if (StringUtils.isNotEmpty(serviceName)) {
             override = overrideService.findOverride(serviceName);
         } else if(StringUtils.isNotEmpty(application)){
             override = overrideService.findOverride(application);
         }
         if (override != null) {
-            override = convertOverrideDTOtoDisplay(override);
             result.add(override);
         }
         return result;
     }
 
     @RequestMapping(value = "/{id}", method = RequestMethod.GET)
-    public OverrideDTO detailOverride(@PathVariable String id, @PathVariable String env) {
-        OverrideDTO override = overrideService.findOverride(id);
+    public DynamicConfigDTO detailOverride(@PathVariable String id, @PathVariable String env) {
+        DynamicConfigDTO override = overrideService.findOverride(id);
         if (override == null) {
             throw new ResourceNotFoundException("Unknown ID!");
         }
 
-        override = convertOverrideDTOtoDisplay(override);
         return override;
     }
 
@@ -117,15 +115,4 @@
         overrideService.disableOverride(id);
         return true;
     }
-
-    private OverrideDTO convertOverrideDTOtoDisplay(OverrideDTO overrideDTO) {
-        if (overrideDTO.getScope().equals("application")) {
-            overrideDTO.setApplication(overrideDTO.getKey());
-        } else {
-            overrideDTO.setService(overrideDTO.getKey());
-        }
-        overrideDTO.setScope(null);
-        overrideDTO.setKey(null);
-        return overrideDTO;
-    }
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/WeightController.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/WeightController.java
index cf91622..2a987f9 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/WeightController.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/WeightController.java
@@ -1,52 +1,58 @@
-///*
-// * 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 org.apache.dubbo.admin.controller;
-//
-//import org.apache.commons.lang3.StringUtils;
-//import org.apache.dubbo.admin.common.exception.ParamValidationException;
-//import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
-//import org.apache.dubbo.admin.model.dto.WeightDTO;
-//import org.apache.dubbo.admin.service.OverrideService;
-//import org.apache.dubbo.admin.model.domain.Override;
-//import org.apache.dubbo.admin.model.domain.Weight;
-//import org.apache.dubbo.admin.common.util.OverrideUtils;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.http.HttpStatus;
-//import org.springframework.web.bind.annotation.*;
-//
-//import java.util.ArrayList;
-//import java.util.List;
-//
-//@RestController
-//@RequestMapping("/api/{env}/rules/weight")
-//public class WeightController {
-//
-//    private final OverrideService overrideService;
-//
-//    @Autowired
-//    public WeightController(OverrideService overrideService) {
-//        this.overrideService = overrideService;
-//    }
-//
-//    @RequestMapping(method = RequestMethod.POST)
-//    @ResponseStatus(HttpStatus.CREATED)
-//    public boolean createWeight(@RequestBody WeightDTO weightDTO, @PathVariable String env) {
-//        String[] addresses = weightDTO.getProvider();
+/*
+ * 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 org.apache.dubbo.admin.controller;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.dubbo.admin.common.exception.ParamValidationException;
+import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
+import org.apache.dubbo.admin.common.util.ConvertUtil;
+import org.apache.dubbo.admin.model.dto.AccessDTO;
+import org.apache.dubbo.admin.model.dto.WeightDTO;
+import org.apache.dubbo.admin.service.OverrideService;
+import org.apache.dubbo.admin.model.domain.Override;
+import org.apache.dubbo.admin.model.domain.Weight;
+import org.apache.dubbo.admin.common.util.OverrideUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/{env}/rules/weight")
+public class WeightController {
+
+    private final OverrideService overrideService;
+
+    @Autowired
+    public WeightController(OverrideService overrideService) {
+        this.overrideService = overrideService;
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    @ResponseStatus(HttpStatus.CREATED)
+    public boolean createWeight(@RequestBody WeightDTO weightDTO, @PathVariable String env) {
+        if (StringUtils.isBlank(weightDTO.getService()) && StringUtils.isBlank(weightDTO.getApplication())) {
+            throw new ParamValidationException("Either Service or application is required.");
+        }
+        overrideService.saveWeight(weightDTO);
+//        List<String> addresses = weightDTO.getAddresses();
 //        for (String address : addresses) {
 //            Weight weight = new Weight();
 //            weight.setService(weightDTO.getService());
@@ -54,30 +60,46 @@
 //            weight.setAddress(address);
 //            overrideService.saveOverride(OverrideUtils.weightToOverride(weight));
 //        }
-//        return true;
-//    }
-//
-//    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
-//    public boolean updateWeight(@PathVariable String id, @RequestBody WeightDTO weightDTO, @PathVariable String env) {
-//        if (id == null) {
-//            throw new ParamValidationException("Unknown ID!");
-//        }
-//        Override override = overrideService.findById(id);
-//        if (override == null) {
-//            throw new ResourceNotFoundException("Unknown ID!");
-//        }
+        return true;
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+    public boolean updateWeight(@PathVariable String id, @RequestBody WeightDTO weightDTO, @PathVariable String env) {
+        if (id == null) {
+            throw new ParamValidationException("Unknown ID!");
+        }
+        WeightDTO weight = overrideService.findWeight(id);
+        if (weight == null) {
+            throw new ResourceNotFoundException("Unknown ID!");
+        }
 //        Weight old = OverrideUtils.overrideToWeight(override);
 //        Weight weight = new Weight();
 //        weight.setWeight(weightDTO.getWeight());
 //        weight.setHash(id);
 //        weight.setService(old.getService());
 //        overrideService.updateOverride(OverrideUtils.weightToOverride(weight));
-//        return true;
-//    }
-//
-//    @RequestMapping(method = RequestMethod.GET)
-//    public List<WeightDTO> searchWeight(@RequestParam(required = false) String service, @PathVariable String env) {
-//        List<Override> overrides;
+        overrideService.updateWeight(weightDTO);
+        return true;
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    public List<WeightDTO> searchWeight(@RequestParam(required = false) String serviceName,
+                                        @RequestParam(required = false) String application,
+                                        @PathVariable String env) {
+        if (StringUtils.isBlank(serviceName) && StringUtils.isBlank(application)) {
+            throw new ParamValidationException("Either service or application is required");
+        }
+        WeightDTO weightDTO;
+        if (StringUtils.isNotBlank(application)) {
+            weightDTO = overrideService.findWeight(application);
+        } else {
+            weightDTO = overrideService.findWeight(serviceName);
+        }
+        List<WeightDTO> weightDTOS = new ArrayList<>();
+        if (weightDTO != null) {
+            weightDTOS.add(weightDTO);
+        }
+
 //        if (StringUtils.isEmpty(service)) {
 //            overrides = overrideService.findAll();
 //        } else {
@@ -88,35 +110,28 @@
 //            Weight w = OverrideUtils.overrideToWeight(override);
 //            if (w != null) {
 //                WeightDTO weightDTO = new WeightDTO();
-//                weightDTO.setProvider(new String[]{w.getAddress()});
+//                weightDTO.setAddresses(new String[]{w.getAddress()});
 //                weightDTO.setService(w.getService());
 //                weightDTO.setWeight(w.getWeight());
 //                weightDTO.setId(w.getHash());
 //                weightDTOS.add(weightDTO);
 //            }
 //        }
-//        return weightDTOS;
-//    }
-//
-//    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
-//    public WeightDTO detailWeight(@PathVariable String id, @PathVariable String env) {
-//        Override override = overrideService.findById(id);
-//        if (override != null) {
-//
-//            Weight w = OverrideUtils.overrideToWeight(override);
-//            WeightDTO weightDTO = new WeightDTO();
-//            weightDTO.setProvider(new String[]{w.getAddress()});
-//            weightDTO.setService(w.getService());
-//            weightDTO.setWeight(w.getWeight());
-//            weightDTO.setId(w.getHash());
-//            return weightDTO;
-//        }
-//        return null;
-//    }
-//
-//    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
-//    public boolean deleteWeight(@PathVariable String id, @PathVariable String env) {
-//        overrideService.deleteOverride(id);
-//        return true;
-//    }
-//}
+        return weightDTOS;
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public WeightDTO detailWeight(@PathVariable String id, @PathVariable String env) {
+        WeightDTO weightDTO = overrideService.findWeight(id);
+        if (weightDTO == null) {
+            throw new ResourceNotFoundException("Unknown ID!");
+        }
+        return weightDTO;
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public boolean deleteWeight(@PathVariable String id, @PathVariable String env) {
+        overrideService.deleteWeight(id);
+        return true;
+    }
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/AccessDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/AccessDTO.java
index 2a12758..8b8e7b4 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/AccessDTO.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/AccessDTO.java
@@ -16,22 +16,22 @@
  */
 package org.apache.dubbo.admin.model.dto;
 
+import java.util.List;
 import java.util.Set;
 
 public class AccessDTO extends BaseDTO {
     // BlackWhiteList key
-    public static final String KEY_BLACK_WHITE_LIST = "blackwhitelist";
 
-    private String service;
     private Set<String> whitelist;
     private Set<String> blacklist;
+    private boolean enabled = true;
 
-    public String getService() {
-        return service;
+    public boolean isEnabled() {
+        return enabled;
     }
 
-    public void setService(String service) {
-        this.service = service;
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
     }
 
     public Set<String> getWhitelist() {
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/BalancingDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/BalancingDTO.java
index 5cd9bbe..585d6f7 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/BalancingDTO.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/BalancingDTO.java
@@ -19,18 +19,9 @@
 
 public class BalancingDTO extends BaseDTO{
 
-    private String service;
     private String methodName;
     private String strategy;
 
-    public String getService() {
-        return service;
-    }
-
-    public void setService(String service) {
-        this.service = service;
-    }
-
     public String getMethodName() {
         return methodName;
     }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/BaseDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/BaseDTO.java
index 874ea94..223b25f 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/BaseDTO.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/BaseDTO.java
@@ -22,13 +22,22 @@
  * For receive ID parameter with @RequestBody
  */
 public abstract class BaseDTO {
-    private String id;
+    private String application;
+    private String service;
 
-    public String getId() {
-        return id;
+    public String getApplication() {
+        return application;
     }
 
-    public void setId(String id) {
-        this.id = id;
+    public void setApplication(String application) {
+        this.application = application;
+    }
+
+    public String getService() {
+        return service;
+    }
+
+    public void setService(String service) {
+        this.service = service;
     }
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/ConditionRouteDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/ConditionRouteDTO.java
index facb268..08de709 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/ConditionRouteDTO.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/ConditionRouteDTO.java
@@ -17,23 +17,16 @@
 
 package org.apache.dubbo.admin.model.dto;
 
+import java.util.List;
+
 public class ConditionRouteDTO extends RouteDTO{
-    private String service;
-    private String[] conditions;
+    private List<String> conditions;
 
-    public String getService() {
-        return service;
-    }
-
-    public void setService(String service) {
-        this.service = service;
-    }
-
-    public String[] getConditions() {
+    public List<String> getConditions() {
         return conditions;
     }
 
-    public void setConditions(String[] conditions) {
+    public void setConditions(List<String> conditions) {
         this.conditions = conditions;
     }
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/domain/OverrideConfig.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/Config.java
similarity index 70%
rename from dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/domain/OverrideConfig.java
rename to dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/Config.java
index 4fa10e4..45f6e96 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/domain/OverrideConfig.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/Config.java
@@ -15,17 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.dubbo.admin.model.domain;
+package org.apache.dubbo.admin.model.dto;
 
+import java.util.List;
 import java.util.Map;
 
-public class OverrideConfig {
+public class Config {
     private String side;
-    private String[] addresses;
-    private String[] providerAddresses;
+    private List<String> addresses;
+    private List<String> providerAddresses;
     private Map<String, Object> parameters;
-    private String[] applications;
-    private String[] services;
+    private List<String> applications;
+    private List<String> services;
 
     public String getSide() {
         return side;
@@ -35,19 +36,19 @@
         this.side = side;
     }
 
-    public String[] getAddresses() {
+    public List<String> getAddresses() {
         return addresses;
     }
 
-    public void setAddresses(String[] addresses) {
+    public void setAddresses(List<String> addresses) {
         this.addresses = addresses;
     }
 
-    public String[] getProviderAddresses() {
+    public List<String> getProviderAddresses() {
         return providerAddresses;
     }
 
-    public void setProviderAddresses(String[] providerAddresses) {
+    public void setProviderAddresses(List<String> providerAddresses) {
         this.providerAddresses = providerAddresses;
     }
 
@@ -59,19 +60,19 @@
         this.parameters = parameters;
     }
 
-    public String[] getApplications() {
+    public List<String> getApplications() {
         return applications;
     }
 
-    public void setApplications(String[] applications) {
+    public void setApplications(List<String> applications) {
         this.applications = applications;
     }
 
-    public String[] getServices() {
+    public List<String> getServices() {
         return services;
     }
 
-    public void setServices(String[] services) {
+    public void setServices(List<String> services) {
         this.services = services;
     }
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/OverrideDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/DynamicConfigDTO.java
similarity index 61%
copy from dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/OverrideDTO.java
copy to dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/DynamicConfigDTO.java
index d3b8516..f44afa7 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/OverrideDTO.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/DynamicConfigDTO.java
@@ -16,41 +16,24 @@
  */
 
 package org.apache.dubbo.admin.model.dto;
-import org.apache.dubbo.admin.model.domain.OverrideConfig;
 
-public class OverrideDTO extends BaseDTO{
+import org.apache.dubbo.admin.model.store.OverrideConfig;
 
-    private String application;
+import java.util.List;
+
+public class DynamicConfigDTO extends BaseDTO {
+
     private String apiVersion;
-    private String service;
     private boolean dynamic;
     private boolean enabled;
-    private String key;
-    private String scope;
-    private OverrideConfig[] configs;
+    private List<OverrideConfig> configs;
 
 
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public String getScope() {
-        return scope;
-    }
-
-    public void setScope(String scope) {
-        this.scope = scope;
-    }
-
-    public OverrideConfig[] getConfigs() {
+    public List<OverrideConfig> getConfigs() {
         return configs;
     }
 
-    public void setConfigs(OverrideConfig[] configs) {
+    public void setConfigs(List<OverrideConfig> configs) {
         this.configs = configs;
     }
 
@@ -62,22 +45,6 @@
         this.apiVersion = apiVersion;
     }
 
-    public String getApplication() {
-        return application;
-    }
-
-    public void setApplication(String application) {
-        this.application = application;
-    }
-
-    public String getService() {
-        return service;
-    }
-
-    public void setService(String service) {
-        this.service = service;
-    }
-
     public boolean isDynamic() {
         return dynamic;
     }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/RouteDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/RouteDTO.java
index 9ad6a61..38ab4e8 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/RouteDTO.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/RouteDTO.java
@@ -23,33 +23,6 @@
     private boolean enabled;
     private boolean force;
     private boolean runtime;
-    private String application;
-    private String key;
-    private String scope;
-
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public String getScope() {
-        return scope;
-    }
-
-    public void setScope(String scope) {
-        this.scope = scope;
-    }
-
-    public String getApplication() {
-        return application;
-    }
-
-    public void setApplication(String application) {
-        this.application = application;
-    }
 
     public boolean isDynamic() {
         return dynamic;
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/TagRouteDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/TagRouteDTO.java
index 69e59ed..85c84f1 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/TagRouteDTO.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/TagRouteDTO.java
@@ -19,15 +19,34 @@
 
 import org.apache.dubbo.admin.model.domain.Tag;
 
-public class TagRouteDTO extends RouteDTO{
-    private Tag[] tags;
+import java.util.List;
 
-    public Tag[] getTags() {
+public class TagRouteDTO extends RouteDTO{
+    private String scope;
+    private String key;
+    private List<Tag> tags;
+
+    public String getScope() {
+        return scope;
+    }
+
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public List<Tag> getTags() {
         return tags;
     }
 
-    public void setTags(Tag[] tags) {
+    public void setTags(List<Tag> tags) {
         this.tags = tags;
     }
-
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/WeightDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/WeightDTO.java
index 1398805..62c73b0 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/WeightDTO.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/WeightDTO.java
@@ -17,19 +17,12 @@
 
 package org.apache.dubbo.admin.model.dto;
 
+import java.util.List;
+
 public class WeightDTO extends BaseDTO{
 
-    private String service;
     private int weight;
-    private String[] provider;
-
-    public String getService() {
-        return service;
-    }
-
-    public void setService(String service) {
-        this.service = service;
-    }
+    private List<String> addresses;
 
     public int getWeight() {
         return weight;
@@ -39,11 +32,11 @@
         this.weight = weight;
     }
 
-    public String[] getProvider() {
-        return provider;
+    public List<String> getAddresses() {
+        return addresses;
     }
 
-    public void setProvider(String[] provider) {
-        this.provider = provider;
+    public void setAddresses(List<String> addresses) {
+        this.addresses = addresses;
     }
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/BlackWhiteList.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/BlackWhiteList.java
new file mode 100644
index 0000000..3072289
--- /dev/null
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/BlackWhiteList.java
@@ -0,0 +1,68 @@
+/*
+ * 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 org.apache.dubbo.admin.model.store;
+
+import java.util.List;
+
+public class BlackWhiteList {
+    private boolean enabled;
+    private boolean force;
+    private boolean runtime;
+    private int priority;
+    private List<String> conditions;
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public boolean isForce() {
+        return force;
+    }
+
+    public void setForce(boolean force) {
+        this.force = force;
+    }
+
+    public boolean isRuntime() {
+        return runtime;
+    }
+
+    public void setRuntime(boolean runtime) {
+        this.runtime = runtime;
+    }
+
+    public int getPriority() {
+        return priority;
+    }
+
+    public void setPriority(int priority) {
+        this.priority = priority;
+    }
+
+    public List<String> getConditions() {
+        return conditions;
+    }
+
+    public void setConditions(List<String> conditions) {
+        this.conditions = conditions;
+    }
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/domain/OverrideConfig.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/OverrideConfig.java
similarity index 62%
copy from dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/domain/OverrideConfig.java
copy to dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/OverrideConfig.java
index 4fa10e4..0a9878e 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/domain/OverrideConfig.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/OverrideConfig.java
@@ -15,17 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.dubbo.admin.model.domain;
+package org.apache.dubbo.admin.model.store;
 
+import java.util.List;
 import java.util.Map;
 
 public class OverrideConfig {
+
     private String side;
-    private String[] addresses;
-    private String[] providerAddresses;
+    private List<String> addresses;
+    private List<String> providerAddresses;
     private Map<String, Object> parameters;
-    private String[] applications;
-    private String[] services;
+    private List<String> applications;
+    private List<String> services;
+    private String type;
+    private boolean enabled;
 
     public String getSide() {
         return side;
@@ -35,19 +39,19 @@
         this.side = side;
     }
 
-    public String[] getAddresses() {
+    public List<String> getAddresses() {
         return addresses;
     }
 
-    public void setAddresses(String[] addresses) {
+    public void setAddresses(List<String> addresses) {
         this.addresses = addresses;
     }
 
-    public String[] getProviderAddresses() {
+    public List<String> getProviderAddresses() {
         return providerAddresses;
     }
 
-    public void setProviderAddresses(String[] providerAddresses) {
+    public void setProviderAddresses(List<String> providerAddresses) {
         this.providerAddresses = providerAddresses;
     }
 
@@ -59,19 +63,35 @@
         this.parameters = parameters;
     }
 
-    public String[] getApplications() {
+    public List<String> getApplications() {
         return applications;
     }
 
-    public void setApplications(String[] applications) {
+    public void setApplications(List<String> applications) {
         this.applications = applications;
     }
 
-    public String[] getServices() {
+    public List<String> getServices() {
         return services;
     }
 
-    public void setServices(String[] services) {
+    public void setServices(List<String> services) {
         this.services = services;
     }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/OverrideDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/OverrideDTO.java
similarity index 72%
rename from dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/OverrideDTO.java
rename to dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/OverrideDTO.java
index d3b8516..7c929d8 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/OverrideDTO.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/OverrideDTO.java
@@ -15,20 +15,19 @@
  * limitations under the License.
  */
 
-package org.apache.dubbo.admin.model.dto;
-import org.apache.dubbo.admin.model.domain.OverrideConfig;
+package org.apache.dubbo.admin.model.store;
 
-public class OverrideDTO extends BaseDTO{
+import org.apache.dubbo.admin.model.dto.Config;
 
-    private String application;
-    private String apiVersion;
-    private String service;
-    private boolean dynamic;
-    private boolean enabled;
+import java.util.List;
+
+public class OverrideDTO {
     private String key;
     private String scope;
-    private OverrideConfig[] configs;
-
+    private String apiVersion;
+    private boolean dynamic;
+    private boolean enabled;
+    private List<OverrideConfig> configs;
 
     public String getKey() {
         return key;
@@ -46,14 +45,6 @@
         this.scope = scope;
     }
 
-    public OverrideConfig[] getConfigs() {
-        return configs;
-    }
-
-    public void setConfigs(OverrideConfig[] configs) {
-        this.configs = configs;
-    }
-
     public String getApiVersion() {
         return apiVersion;
     }
@@ -62,22 +53,6 @@
         this.apiVersion = apiVersion;
     }
 
-    public String getApplication() {
-        return application;
-    }
-
-    public void setApplication(String application) {
-        this.application = application;
-    }
-
-    public String getService() {
-        return service;
-    }
-
-    public void setService(String service) {
-        this.service = service;
-    }
-
     public boolean isDynamic() {
         return dynamic;
     }
@@ -93,4 +68,12 @@
     public void setEnabled(boolean enabled) {
         this.enabled = enabled;
     }
+
+    public List<OverrideConfig> getConfigs() {
+        return configs;
+    }
+
+    public void setConfigs(List<OverrideConfig> configs) {
+        this.configs = configs;
+    }
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/RoutingRuleDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/RoutingRuleDTO.java
new file mode 100644
index 0000000..5498a56
--- /dev/null
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/store/RoutingRuleDTO.java
@@ -0,0 +1,106 @@
+/*
+ * 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 org.apache.dubbo.admin.model.store;
+
+import java.util.List;
+
+public class RoutingRuleDTO {
+
+    private String key;
+    private String scope;
+    private boolean dynamic;
+    private int priority;
+    private boolean enabled;
+    private boolean force;
+    private boolean runtime;
+    private List<String> conditions;
+    private BlackWhiteList blackWhiteList;
+
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getScope() {
+        return scope;
+    }
+
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+
+    public boolean isDynamic() {
+        return dynamic;
+    }
+
+    public void setDynamic(boolean dynamic) {
+        this.dynamic = dynamic;
+    }
+
+    public int getPriority() {
+        return priority;
+    }
+
+    public void setPriority(int priority) {
+        this.priority = priority;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public boolean isForce() {
+        return force;
+    }
+
+    public void setForce(boolean force) {
+        this.force = force;
+    }
+
+    public boolean isRuntime() {
+        return runtime;
+    }
+
+    public void setRuntime(boolean runtime) {
+        this.runtime = runtime;
+    }
+
+    public List<String> getConditions() {
+        return conditions;
+    }
+
+    public void setConditions(List<String> conditions) {
+        this.conditions = conditions;
+    }
+
+    public BlackWhiteList getBlackWhiteList() {
+        return blackWhiteList;
+    }
+
+    public void setBlackWhiteList(BlackWhiteList blackWhiteList) {
+        this.blackWhiteList = blackWhiteList;
+    }
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/OverrideService.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/OverrideService.java
index c549c10..b17b96f 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/OverrideService.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/OverrideService.java
@@ -16,13 +16,15 @@
  */
 package org.apache.dubbo.admin.service;
 
-import org.apache.dubbo.admin.model.dto.OverrideDTO;
+import org.apache.dubbo.admin.model.dto.BalancingDTO;
+import org.apache.dubbo.admin.model.dto.DynamicConfigDTO;
+import org.apache.dubbo.admin.model.dto.WeightDTO;
 
 public interface OverrideService {
 
-    void saveOverride(OverrideDTO override);
+    void saveOverride(DynamicConfigDTO override);
 
-    void updateOverride(OverrideDTO old, OverrideDTO override);
+    void updateOverride(DynamicConfigDTO override);
 
     void deleteOverride(String id);
 
@@ -30,6 +32,22 @@
 
     void disableOverride(String id);
 
-    OverrideDTO findOverride(String service);
+    DynamicConfigDTO findOverride(String id);
+
+    void saveWeight(WeightDTO weightDTO);
+
+    void updateWeight(WeightDTO weightDTO);
+
+    void deleteWeight(String id);
+
+    WeightDTO findWeight(String id);
+
+    void saveBalance(BalancingDTO balancingDTO);
+
+    void updateBalance(BalancingDTO balancingDTO);
+
+    void deleteBalance(String id);
+
+    BalancingDTO findBalance(String id);
 
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/RouteService.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/RouteService.java
index 6d7b780..6827103 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/RouteService.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/RouteService.java
@@ -16,6 +16,7 @@
  */
 package org.apache.dubbo.admin.service;
 
+import org.apache.dubbo.admin.model.dto.AccessDTO;
 import org.apache.dubbo.admin.model.dto.ConditionRouteDTO;
 import org.apache.dubbo.admin.model.dto.TagRouteDTO;
 
@@ -27,10 +28,17 @@
 
     void createConditionRoute(ConditionRouteDTO conditionRoute);
 
-    void updateConditionRoute(ConditionRouteDTO oldConditionRoute, ConditionRouteDTO conditionRoute);
+    void updateConditionRoute(ConditionRouteDTO newConditionRoute);
 
     void deleteConditionRoute(String id);
 
+    void deleteAccess(String id);
+
+    void createAccess(AccessDTO accessDTO);
+
+    AccessDTO findAccess(String id);
+
+    void updateAccess(AccessDTO accessDTO);
 
     void enableConditionRoute(String id);
 
@@ -38,7 +46,7 @@
     void disableConditionRoute(String id);
 
 
-    ConditionRouteDTO findConditionRoute(String serviceName);
+    ConditionRouteDTO findConditionRoute(String id);
 
     void createTagRoute(TagRouteDTO tagRoute);
 
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/OverrideServiceImpl.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/OverrideServiceImpl.java
index 2f1d7da..dc4eef6 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/OverrideServiceImpl.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/OverrideServiceImpl.java
@@ -18,10 +18,18 @@
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.admin.common.util.Constants;
+import org.apache.dubbo.admin.common.util.ConvertUtil;
+import org.apache.dubbo.admin.common.util.OverrideUtils;
 import org.apache.dubbo.admin.common.util.YamlParser;
+import org.apache.dubbo.admin.model.domain.LoadBalance;
 import org.apache.dubbo.admin.model.domain.Override;
-import org.apache.dubbo.admin.model.domain.OverrideConfig;
-import org.apache.dubbo.admin.model.dto.OverrideDTO;
+import org.apache.dubbo.admin.model.dto.Config;
+import org.apache.dubbo.admin.model.domain.Weight;
+import org.apache.dubbo.admin.model.dto.BalancingDTO;
+import org.apache.dubbo.admin.model.dto.DynamicConfigDTO;
+import org.apache.dubbo.admin.model.dto.WeightDTO;
+import org.apache.dubbo.admin.model.store.OverrideConfig;
+import org.apache.dubbo.admin.model.store.OverrideDTO;
 import org.apache.dubbo.admin.service.OverrideService;
 import org.springframework.stereotype.Component;
 
@@ -39,13 +47,28 @@
     private String prefix = Constants.CONFIG_KEY;
 
     @java.lang.Override
-    public void saveOverride(OverrideDTO override) {
-        override = convertOverrideDTOtoStore(override);
-        String path = getPath(override.getKey());
-        dynamicConfiguration.setConfig(path, YamlParser.dumpObject(override));
+    public void saveOverride(DynamicConfigDTO override) {
+        String id = ConvertUtil.getIdFromDTO(override);
+        String path = getPath(id);
+        String exitConfig = dynamicConfiguration.getConfig(path);
+        List<OverrideConfig> configs = new ArrayList<>();
+        OverrideDTO existOverride = OverrideUtils.createFromDynamicConfig(override);
+        if (exitConfig != null) {
+            existOverride = YamlParser.loadObject(exitConfig, OverrideDTO.class);
+            if (existOverride.getConfigs() != null) {
+                for (OverrideConfig overrideConfig : existOverride.getConfigs()) {
+                    if (Constants.CONFIGS.contains(overrideConfig.getType())) {
+                        configs.add(overrideConfig);
+                    }
+                }
+            }
+        }
+        configs.addAll(override.getConfigs());
+        existOverride.setConfigs(configs);
+        dynamicConfiguration.setConfig(path, YamlParser.dumpObject(existOverride));
 
         //for2.6
-        if (override.getScope().equals("service")) {
+        if (StringUtils.isNotEmpty(override.getService())) {
             List<Override> result = convertDTOtoOldOverride(override);
             for (Override o : result) {
                 registry.register(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
@@ -54,17 +77,30 @@
     }
 
     @java.lang.Override
-    public void updateOverride(OverrideDTO old, OverrideDTO update) {
-        old = convertOverrideDTOtoStore(old);
-        update = convertOverrideDTOtoStore(update);
-        String path = getPath(update.getKey());
-        if (dynamicConfiguration.getConfig(path) == null) {
+    public void updateOverride(DynamicConfigDTO update) {
+        String id = ConvertUtil.getIdFromDTO(update);
+        String path = getPath(id);
+        String exitConfig = dynamicConfiguration.getConfig(path);
+        if (exitConfig == null) {
             //throw exception
         }
+        OverrideDTO overrideDTO = YamlParser.loadObject(exitConfig, OverrideDTO.class);
+        DynamicConfigDTO old = OverrideUtils.createFromOverride(overrideDTO);
+        List<OverrideConfig> configs = new ArrayList<>();
+        if (overrideDTO.getConfigs() != null) {
+            List<OverrideConfig> overrideConfigs = overrideDTO.getConfigs();
+            for (OverrideConfig config : overrideConfigs) {
+                if (Constants.CONFIGS.contains(config.getType())) {
+                    configs.add(config);
+                }
+            }
+        }
+        configs.addAll(update.getConfigs());
+        overrideDTO.setConfigs(configs);
         dynamicConfiguration.setConfig(path, YamlParser.dumpObject(update));
 
         //for 2.6
-        if (update.getScope().equals("service")) {
+        if (StringUtils.isNotEmpty(update.getService())) {
             List<Override> oldOverrides = convertDTOtoOldOverride(old);
             List<Override> updatedOverrides = convertDTOtoOldOverride(update);
             for (Override o : oldOverrides) {
@@ -86,12 +122,28 @@
         if (config == null) {
             //throw exception
         }
-        dynamicConfiguration.deleteConfig(path);
+        OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
+        DynamicConfigDTO old = OverrideUtils.createFromOverride(overrideDTO);
+        List<OverrideConfig> newConfigs = new ArrayList<>();
+        if (overrideDTO.getConfigs() != null && overrideDTO.getConfigs().size() > 0) {
+            for (OverrideConfig overrideConfig : overrideDTO.getConfigs()) {
+                if (Constants.CONFIGS.contains(overrideConfig.getType())) {
+                    newConfigs.add(overrideConfig);
+                }
+            }
+            if (newConfigs.size() == 0) {
+                dynamicConfiguration.deleteConfig(path);
+            } else {
+                overrideDTO.setConfigs(newConfigs);
+                dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
+            }
+        } else {
+            dynamicConfiguration.deleteConfig(path);
+        }
 
         //for 2.6
-        OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
-        if (overrideDTO.getScope().equals("service")) {
-            List<Override> overrides = convertDTOtoOldOverride(overrideDTO);
+        if (overrideDTO.getScope().equals(Constants.SERVICE)) {
+            List<Override> overrides = convertDTOtoOldOverride(old);
             for (Override o : overrides) {
                 registry.unregister(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
             }
@@ -109,12 +161,13 @@
             //throw exception
         }
         OverrideDTO override = YamlParser.loadObject(config, OverrideDTO.class);
+        DynamicConfigDTO old = OverrideUtils.createFromOverride(override);
         override.setEnabled(true);
         dynamicConfiguration.setConfig(path, YamlParser.dumpObject(override));
 
         //2.6
-        if (override.getScope().equals("service")) {
-            List<Override> overrides = convertDTOtoOldOverride(override);
+        if (override.getScope().equals(Constants.SERVICE)) {
+            List<Override> overrides = convertDTOtoOldOverride(old);
             for (Override o : overrides) {
                 o.setEnabled(false);
                 registry.unregister(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
@@ -135,12 +188,13 @@
         }
         String config = dynamicConfiguration.getConfig(path);
         OverrideDTO override = YamlParser.loadObject(config, OverrideDTO.class);
+        DynamicConfigDTO old = OverrideUtils.createFromOverride(override);
         override.setEnabled(false);
         dynamicConfiguration.setConfig(path, YamlParser.dumpObject(override));
 
         //for 2.6
-        if (override.getScope().equals("service")) {
-            List<Override> overrides = convertDTOtoOldOverride(override);
+        if (override.getScope().equals(Constants.SERVICE)) {
+            List<Override> overrides = convertDTOtoOldOverride(old);
             for (Override o : overrides) {
                 o.setEnabled(true);
                 registry.unregister(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
@@ -151,28 +205,255 @@
     }
 
     @java.lang.Override
-    public OverrideDTO findOverride(String id) {
+    public DynamicConfigDTO findOverride(String id) {
         if (StringUtils.isEmpty(id)) {
             //throw exception
         }
         String path = getPath(id);
         String config = dynamicConfiguration.getConfig(path);
         if (config != null) {
-            return YamlParser.loadObject(config, OverrideDTO.class);
+            OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
+            return OverrideUtils.createFromOverride(overrideDTO);
         }
         return null;
     }
 
-    private OverrideDTO convertOverrideDTOtoStore(OverrideDTO overrideDTO) {
-        if (StringUtils.isNotEmpty(overrideDTO.getApplication())) {
-           overrideDTO.setScope("application");
-           overrideDTO.setKey(overrideDTO.getApplication());
-        } else {
-            overrideDTO.setScope("service");
-            overrideDTO.setKey(overrideDTO.getService());
+    @java.lang.Override
+    public void saveWeight(WeightDTO weightDTO) {
+        String id = ConvertUtil.getIdFromDTO(weightDTO);
+        String scope = ConvertUtil.getScopeFromDTO(weightDTO);
+        String path = getPath(id);
+        String config = dynamicConfiguration.getConfig(path);
+        OverrideConfig overrideConfig = OverrideUtils.weightDTOtoConfig(weightDTO);
+        OverrideDTO overrideDTO = insertConfig(config, overrideConfig, id, scope);
+        dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
+
+        //for 2.6
+        if (scope.equals(Constants.SERVICE)) {
+            registerWeight(weightDTO);
         }
-        overrideDTO.setApplication(null);
-        overrideDTO.setService(null);
+
+    }
+
+    @java.lang.Override
+    public void updateWeight(WeightDTO weightDTO) {
+        String id = ConvertUtil.getIdFromDTO(weightDTO);
+        String scope = ConvertUtil.getScopeFromDTO(weightDTO);
+        String path = getPath(id);
+        String config = dynamicConfiguration.getConfig(path);
+        WeightDTO oldWeight = null;
+        if (config != null) {
+            OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
+            List<OverrideConfig> configs = overrideDTO.getConfigs();
+            if (configs != null && configs.size() > 0) {
+                for (OverrideConfig overrideConfig : configs) {
+                    if (Constants.WEIGHT.equals(overrideConfig.getType())) {
+                        if (overrideDTO.getScope().equals(Constants.SERVICE)) {
+                            oldWeight = OverrideUtils.configtoWeightDTO(overrideConfig, scope, id);
+                        }
+                        int index = configs.indexOf(overrideConfig);
+                        OverrideConfig newConfig = OverrideUtils.weightDTOtoConfig(weightDTO);
+                        configs.set(index, newConfig);
+                        break;
+                    }
+                }
+                dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
+            } else {
+                //throw exception
+            }
+        } else {
+            //throw exception
+        }
+
+
+        //for 2.6
+        if (oldWeight != null) {
+            unregisterWeight(oldWeight);
+            registerWeight(weightDTO);
+        }
+
+    }
+
+    @java.lang.Override
+    public void deleteWeight(String id) {
+        String path = getPath(id);
+        String config = dynamicConfiguration.getConfig(path);
+        OverrideConfig oldConfig = null;
+        if (config != null) {
+            OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
+            List<OverrideConfig> configs = overrideDTO.getConfigs();
+            if (configs != null) {
+                for (OverrideConfig overrideConfig : configs) {
+                    if (Constants.WEIGHT.equals(overrideConfig.getType())) {
+                        if (overrideDTO.getScope().equals(Constants.SERVICE)) {
+                            oldConfig = overrideConfig;
+                        }
+                        configs.remove(overrideConfig);
+                        break;
+                    }
+                }
+                if (configs.size() == 0) {
+                    dynamicConfiguration.deleteConfig(path);
+                } else {
+                    dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
+                }
+
+            }
+
+            //for 2.6
+            if (oldConfig != null) {
+                String key = overrideDTO.getKey();
+                WeightDTO weightDTO = OverrideUtils.configtoWeightDTO(oldConfig, overrideDTO.getScope(), key);
+                unregisterWeight(weightDTO);
+            }
+        }
+    }
+
+    @java.lang.Override
+    public WeightDTO findWeight(String id) {
+        String path = getPath(id);
+        String config = dynamicConfiguration.getConfig(path);
+        if (config != null) {
+            OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
+            List<OverrideConfig> configs = overrideDTO.getConfigs();
+            if (configs != null) {
+                for (OverrideConfig overrideConfig : configs) {
+                    if (Constants.WEIGHT.equals(overrideConfig.getType())) {
+                        WeightDTO weightDTO = OverrideUtils.configtoWeightDTO(overrideConfig, overrideDTO.getScope(), id);
+                        return weightDTO;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    @java.lang.Override
+    public void saveBalance(BalancingDTO balancingDTO) {
+        String id = ConvertUtil.getIdFromDTO(balancingDTO);
+        String scope = ConvertUtil.getScopeFromDTO(balancingDTO);
+        String path = getPath(id);
+        String config = dynamicConfiguration.getConfig(path);
+        OverrideConfig overrideConfig = OverrideUtils.balanceDTOtoConfig(balancingDTO);
+        OverrideDTO overrideDTO = insertConfig(config, overrideConfig, id, scope);
+        dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
+
+        //for 2.6
+
+        if (scope.equals(Constants.SERVICE)) {
+            registerBalancing(balancingDTO);
+        }
+    }
+
+    @java.lang.Override
+    public void updateBalance(BalancingDTO balancingDTO) {
+        String id = ConvertUtil.getIdFromDTO(balancingDTO);
+        String scope = ConvertUtil.getScopeFromDTO(balancingDTO);
+        String path = getPath(id);
+        String config = dynamicConfiguration.getConfig(path);
+        BalancingDTO oldBalancing = null;
+        if (config != null) {
+            OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
+            List<OverrideConfig> configs = overrideDTO.getConfigs();
+            if (configs != null && configs.size() > 0) {
+                for (OverrideConfig overrideConfig : configs) {
+                    if (Constants.BALANCING.equals(overrideConfig.getType())) {
+                        if (overrideDTO.getScope().equals(Constants.SERVICE)) {
+                            oldBalancing = OverrideUtils.configtoBalancingDTO(overrideConfig, Constants.SERVICE, overrideDTO.getKey());
+                        }
+                        int index = configs.indexOf(overrideConfig);
+                        OverrideConfig newConfig = OverrideUtils.balanceDTOtoConfig(balancingDTO);
+                        configs.set(index, newConfig);
+                        break;
+                    }
+                }
+                dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
+            } else {
+                //throw exception
+            }
+        } else {
+            //throw exception
+        }
+
+        //for 2.6
+        if (oldBalancing != null) {
+            unregisterBalancing(oldBalancing);
+            registerBalancing(balancingDTO);
+        }
+    }
+
+    @java.lang.Override
+    public void deleteBalance(String id) {
+        String path = getPath(id);
+        String config = dynamicConfiguration.getConfig(path);
+        OverrideConfig oldConfig = null;
+        if (config != null) {
+            OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
+            List<OverrideConfig> configs = overrideDTO.getConfigs();
+            if (configs != null) {
+                for (OverrideConfig overrideConfig : configs) {
+                    if (Constants.BALANCING.equals(overrideConfig.getType())) {
+                        if (overrideDTO.getScope().equals(Constants.SERVICE)) {
+                            oldConfig = overrideConfig;
+                        }
+                        configs.remove(overrideConfig);
+                        break;
+                    }
+                }
+                if (configs.size() == 0) {
+                    dynamicConfiguration.deleteConfig(path);
+                } else {
+                    dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
+                }
+            }
+            //for 2.6
+            if (oldConfig != null) {
+                String key = overrideDTO.getKey();
+                BalancingDTO balancingDTO = OverrideUtils.configtoBalancingDTO(oldConfig, Constants.SERVICE, key);
+                unregisterBalancing(balancingDTO);
+            }
+        }
+    }
+
+    @java.lang.Override
+    public BalancingDTO findBalance(String id) {
+        String path = getPath(id);
+        String config = dynamicConfiguration.getConfig(path);
+        if (config != null) {
+            OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
+            List<OverrideConfig> configs = overrideDTO.getConfigs();
+            if (configs != null) {
+                for (OverrideConfig overrideConfig : configs) {
+                    if (Constants.BALANCING.equals(overrideConfig.getType())) {
+                        BalancingDTO balancingDTO = OverrideUtils.configtoBalancingDTO(overrideConfig, overrideDTO.getScope(), id);
+                        return balancingDTO;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private OverrideDTO insertConfig(String config, OverrideConfig overrideConfig, String key, String scope) {
+        OverrideDTO overrideDTO = null;
+        if(config == null) {
+            overrideDTO = new OverrideDTO();
+            overrideDTO.setKey(key);
+            overrideDTO.setScope(scope);
+            List<OverrideConfig> configs = new ArrayList<>();
+            configs.add(overrideConfig);
+            overrideDTO.setConfigs(configs);
+        } else {
+            overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
+            List<OverrideConfig> configs = overrideDTO.getConfigs();
+            if (configs != null) {
+                configs.add(overrideConfig);
+            } else {
+                configs = new ArrayList<>();
+                configs.add(overrideConfig);
+            }
+            overrideDTO.setConfigs(configs);
+        }
         return overrideDTO;
     }
 
@@ -194,17 +475,20 @@
         }
         override.setParams(params.toString());
     }
-    private List<Override> convertDTOtoOldOverride(OverrideDTO overrideDTO) {
+    private List<Override> convertDTOtoOldOverride(DynamicConfigDTO overrideDTO) {
         List<Override> result = new ArrayList<>();
-        OverrideConfig[] configs = overrideDTO.getConfigs();
+        List<OverrideConfig> configs = overrideDTO.getConfigs();
         for (OverrideConfig config : configs) {
-            String[] apps = config.getApplications();
-            String[] addresses = config.getAddresses();
+            if (Constants.CONFIGS.contains(config.getType())) {
+                continue;
+            }
+            List<String> apps = config.getApplications();
+            List<String> addresses = config.getAddresses();
             for (String address : addresses) {
-                if (apps != null && apps.length > 0) {
+                if (apps != null && apps.size() > 0) {
                     for (String app : apps) {
                         Override override = new Override();
-                        override.setService(overrideDTO.getKey());
+                        override.setService(overrideDTO.getService());
                         override.setAddress(address);
                         override.setEnabled(overrideDTO.isEnabled());
                         overrideDTOToParams(override, config);
@@ -213,7 +497,7 @@
                     }
                 } else {
                     Override override = new Override();
-                    override.setService(overrideDTO.getKey());
+                    override.setService(overrideDTO.getService());
                     override.setAddress(address);
                     override.setEnabled(overrideDTO.isEnabled());
                     overrideDTOToParams(override, config);
@@ -224,7 +508,59 @@
         return result;
     }
     private String getPath(String key) {
-        return prefix + Constants.PATH_SEPARATOR + key + Constants.PATH_SEPARATOR + "configurators";
+        return prefix + Constants.PATH_SEPARATOR + key + Constants.PATH_SEPARATOR + Constants.CONFIGURATOR;
+    }
+
+    private String formatMethodName(String method) {
+        if (method.equals("0")) {
+            return "*";
+        }
+        return method;
+    }
+
+    private void unregisterWeight(WeightDTO weightDTO) {
+        List<String> addresses = weightDTO.getAddresses();
+        if (addresses != null) {
+            for (String address : addresses) {
+                Weight weight = new Weight();
+                weight.setService(weightDTO.getService());
+                weight.setAddress(address);
+                weight.setWeight(weightDTO.getWeight());
+                Override override = OverrideUtils.weightToOverride(weight);
+                registry.unregister(override.toUrl());
+            }
+        }
+    }
+
+    private void registerWeight(WeightDTO weightDTO) {
+        List<String> addresses = weightDTO.getAddresses();
+        if (addresses != null) {
+            for (String address : addresses) {
+                Weight weight = new Weight();
+                weight.setService(weightDTO.getService());
+                weight.setAddress(address);
+                weight.setWeight(weightDTO.getWeight());
+                Override override = OverrideUtils.weightToOverride(weight);
+                registry.register(override.toUrl());
+            }
+
+        }
+    }
+
+    private void unregisterBalancing(BalancingDTO balancingDTO) {
+        LoadBalance loadBalance = new LoadBalance();
+        loadBalance.setService(balancingDTO.getService());
+        loadBalance.setMethod(formatMethodName(balancingDTO.getMethodName()));
+        loadBalance.setStrategy(balancingDTO.getStrategy());
+        registry.unregister(OverrideUtils.loadBalanceToOverride(loadBalance).toUrl());
+    }
+
+    private void registerBalancing(BalancingDTO balancingDTO) {
+        LoadBalance loadBalance = new LoadBalance();
+        loadBalance.setService(balancingDTO.getService());
+        loadBalance.setMethod(formatMethodName(balancingDTO.getMethodName()));
+        loadBalance.setStrategy(balancingDTO.getStrategy());
+        registry.register(OverrideUtils.loadBalanceToOverride(loadBalance).toUrl());
     }
 
 }
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java
index a420dfc..346d01d 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java
@@ -18,15 +18,23 @@
 
 import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
 import org.apache.dubbo.admin.common.util.Constants;
+import org.apache.dubbo.admin.common.util.ConvertUtil;
+import org.apache.dubbo.admin.common.util.RouteRule;
 import org.apache.dubbo.admin.common.util.YamlParser;
 import org.apache.dubbo.admin.model.domain.Route;
+import org.apache.dubbo.admin.model.dto.AccessDTO;
 import org.apache.dubbo.admin.model.dto.ConditionRouteDTO;
 import org.apache.dubbo.admin.model.dto.TagRouteDTO;
+import org.apache.dubbo.admin.model.store.BlackWhiteList;
+import org.apache.dubbo.admin.model.store.RoutingRuleDTO;
 import org.apache.dubbo.admin.service.RouteService;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.springframework.stereotype.Component;
 
+import java.time.YearMonth;
+import java.util.List;
+
 /**
  * IbatisRouteService
  *
@@ -38,13 +46,19 @@
 
     @Override
     public void createConditionRoute(ConditionRouteDTO conditionRoute) {
-        conditionRoute = convertRouteDTOtoStore(conditionRoute);
-        String path = getPath(conditionRoute.getKey(),Constants.CONDITION_ROUTE);
+        String id = ConvertUtil.getIdFromDTO(conditionRoute);
+        String path = getPath(id, Constants.CONDITION_ROUTE);
+        String existConfig = dynamicConfiguration.getConfig(path);
+        RoutingRuleDTO existRule = null;
+        if (existConfig != null) {
+            existRule = YamlParser.loadObject(existConfig, RoutingRuleDTO.class);
+        }
+        existRule = RouteRule.insertConditionRule(existRule, conditionRoute);
         //register2.7
-        dynamicConfiguration.setConfig(path, YamlParser.dumpObject(conditionRoute));
+        dynamicConfiguration.setConfig(path, YamlParser.dumpObject(existRule));
 
         //register2.6
-        if (conditionRoute.getScope().equals("service")) {
+        if (StringUtils.isNotEmpty(conditionRoute.getService())) {
             Route old = convertRouteToOldRoute(conditionRoute);
             registry.register(old.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
         }
@@ -52,16 +66,20 @@
     }
 
     @Override
-    public void updateConditionRoute(ConditionRouteDTO oldConditionRoute, ConditionRouteDTO newConditionRoute) {
-        oldConditionRoute = convertRouteDTOtoStore(oldConditionRoute);
-        newConditionRoute = convertRouteDTOtoStore(newConditionRoute);
-        String path = getPath(newConditionRoute.getKey(), Constants.CONDITION_ROUTE);
-        if (dynamicConfiguration.getConfig(path) == null) {
+    public void updateConditionRoute(ConditionRouteDTO newConditionRoute) {
+        String id = ConvertUtil.getIdFromDTO(newConditionRoute);
+        String path = getPath(id, Constants.CONDITION_ROUTE);
+        String existConfig = dynamicConfiguration.getConfig(path);
+        if (existConfig == null) {
             throw new ResourceNotFoundException("no existing condition route for path: " + path);
         }
-        dynamicConfiguration.setConfig(path, YamlParser.dumpObject(newConditionRoute));
+        RoutingRuleDTO routingRuleDTO = YamlParser.loadObject(existConfig, RoutingRuleDTO.class);
+        ConditionRouteDTO oldConditionRoute = RouteRule.createConditionRouteFromRule(routingRuleDTO);
+        routingRuleDTO = RouteRule.insertConditionRule(routingRuleDTO, newConditionRoute);
+        dynamicConfiguration.setConfig(path, YamlParser.dumpObject(routingRuleDTO));
 
-        if (newConditionRoute.getScope().equals("service")) {
+        //for 2.6
+        if (StringUtils.isNotEmpty(newConditionRoute.getService())) {
             Route old = convertRouteToOldRoute(oldConditionRoute);
             Route updated = convertRouteToOldRoute(newConditionRoute);
             registry.unregister(old.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
@@ -70,40 +88,140 @@
     }
 
     @Override
-    public void deleteConditionRoute(String serviceName) {
-        String path = getPath(serviceName, Constants.CONDITION_ROUTE);
+    public void deleteConditionRoute(String id) {
+        if (StringUtils.isEmpty(id)) {
+            // throw exception
+        }
+        String path = getPath(id, Constants.CONDITION_ROUTE);
         String config = dynamicConfiguration.getConfig(path);
-        dynamicConfiguration.deleteConfig(path);
+        if (config == null) {
+            //throw exception
+        }
+        RoutingRuleDTO route = YamlParser.loadObject(config, RoutingRuleDTO.class);
+        if (route.getBlackWhiteList() != null) {
+           route.setConditions(null);
+            dynamicConfiguration.setConfig(path, YamlParser.dumpObject(route));
+        } else {
+            dynamicConfiguration.deleteConfig(path);
+        }
 
         //for 2.6
-        if (StringUtils.isNoneEmpty(config)) {
-            ConditionRouteDTO route = YamlParser.loadObject(config, ConditionRouteDTO.class);
-            if (route.getScope().equals("service")) {
-                Route old = convertRouteToOldRoute(route);
-                registry.unregister(old.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
+        if (route.getScope().equals(Constants.SERVICE)) {
+            RoutingRuleDTO originRule = YamlParser.loadObject(config, RoutingRuleDTO.class);
+            ConditionRouteDTO conditionRouteDTO = RouteRule.createConditionRouteFromRule(originRule);
+            Route old = convertRouteToOldRoute(conditionRouteDTO);
+            registry.unregister(old.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
+        }
+    }
+
+    @Override
+    public void deleteAccess(String id) {
+        String path = getPath(id, Constants.CONDITION_ROUTE);
+        String config = dynamicConfiguration.getConfig(path);
+        if (config != null) {
+            RoutingRuleDTO ruleDTO = YamlParser.loadObject(config, RoutingRuleDTO.class);
+            BlackWhiteList old = ruleDTO.getBlackWhiteList();
+            if (ruleDTO.getConditions() == null) {
+                dynamicConfiguration.deleteConfig(path);
+            } else {
+                ruleDTO.setBlackWhiteList(null);
+                dynamicConfiguration.setConfig(path, YamlParser.dumpObject(ruleDTO));
+            }
+            //2.6
+            if (ruleDTO.getScope().equals(Constants.SERVICE) && old != null) {
+                Route route = RouteRule.convertBlackWhiteListtoRoute(old, Constants.SERVICE, id);
+                registry.unregister(route.toUrl());
             }
         }
     }
 
+    @Override
+    public void createAccess(AccessDTO accessDTO) {
+        String id = ConvertUtil.getIdFromDTO(accessDTO);
+        String path = getPath(id, Constants.CONDITION_ROUTE);
+        String config = dynamicConfiguration.getConfig(path);
+        BlackWhiteList blackWhiteList = RouteRule.convertToBlackWhiteList(accessDTO);
+        RoutingRuleDTO ruleDTO;
+        if (config == null) {
+            ruleDTO = new RoutingRuleDTO();
+            ruleDTO.setEnabled(true);
+            if (StringUtils.isNoneEmpty(accessDTO.getApplication())) {
+                ruleDTO.setScope(Constants.APPLICATION);
+            } else {
+                ruleDTO.setScope(Constants.SERVICE);
+            }
+            ruleDTO.setKey(id);
+            ruleDTO.setBlackWhiteList(blackWhiteList);
+        } else {
+            ruleDTO = YamlParser.loadObject(config, RoutingRuleDTO.class);
+            if (ruleDTO.getBlackWhiteList() != null) {
+                //todo throw exception
+            }
+            ruleDTO.setBlackWhiteList(blackWhiteList);
+        }
+        dynamicConfiguration.setConfig(path, YamlParser.dumpObject(ruleDTO));
+
+        //for 2.6
+        if (ruleDTO.getScope().equals("service")) {
+            Route route = RouteRule.convertAccessDTOtoRoute(accessDTO);
+            registry.register(route.toUrl());
+        }
+
+    }
 
     @Override
-    public void enableConditionRoute(String serviceName) {
-        String path = getPath(serviceName, Constants.CONDITION_ROUTE);
+    public AccessDTO findAccess(String id) {
+        String path = getPath(id, Constants.CONDITION_ROUTE);
         String config = dynamicConfiguration.getConfig(path);
         if (config != null) {
-            ConditionRouteDTO conditionRoute = YamlParser.loadObject(config, ConditionRouteDTO.class);
+            RoutingRuleDTO ruleDTO = YamlParser.loadObject(config, RoutingRuleDTO.class);
+            BlackWhiteList blackWhiteList = ruleDTO.getBlackWhiteList();
+            return RouteRule.convertToAccessDTO(blackWhiteList, ruleDTO.getScope(), ruleDTO.getKey());
+        }
+        return null;
+    }
 
-            if (conditionRoute.getScope().equals("service")) {
+    @Override
+    public void updateAccess(AccessDTO accessDTO) {
+        String key = ConvertUtil.getIdFromDTO(accessDTO);
+        String path = getPath(key, Constants.CONDITION_ROUTE);
+        BlackWhiteList blackWhiteList = RouteRule.convertToBlackWhiteList(accessDTO);
+        BlackWhiteList old = null;
+        String config = dynamicConfiguration.getConfig(path);
+        if (config != null) {
+            RoutingRuleDTO ruleDTO = YamlParser.loadObject(config, RoutingRuleDTO.class);
+            old = ruleDTO.getBlackWhiteList();
+            ruleDTO.setBlackWhiteList(blackWhiteList);
+            dynamicConfiguration.setConfig(path, YamlParser.dumpObject(ruleDTO));
+        }
+
+        //2.6
+        if (StringUtils.isNotEmpty(accessDTO.getService())) {
+            Route oldRoute = RouteRule.convertBlackWhiteListtoRoute(old, Constants.SERVICE, key);
+            Route newRoute = RouteRule.convertAccessDTOtoRoute(accessDTO);
+            registry.unregister(oldRoute.toUrl());
+            registry.register(newRoute.toUrl());
+        }
+    }
+
+    @Override
+    public void enableConditionRoute(String id) {
+        String path = getPath(id, Constants.CONDITION_ROUTE);
+        String config = dynamicConfiguration.getConfig(path);
+        if (config != null) {
+            RoutingRuleDTO ruleDTO = YamlParser.loadObject(config, RoutingRuleDTO.class);
+
+            if (ruleDTO.getScope().equals(Constants.SERVICE)) {
                 //for2.6
-                URL oldURL = convertRouteToOldRoute(conditionRoute).toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true);
+                URL oldURL = convertRouteToOldRoute(RouteRule.createConditionRouteFromRule(ruleDTO)).toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true);
                 registry.unregister(oldURL);
                 oldURL = oldURL.addParameter("enabled", true);
                 registry.register(oldURL);
             }
 
             //2.7
-            conditionRoute.setEnabled(true);
-            dynamicConfiguration.setConfig(path, YamlParser.dumpObject(conditionRoute));
+            ruleDTO.setEnabled(true);
+            dynamicConfiguration.setConfig(path, YamlParser.dumpObject(ruleDTO));
         }
 
     }
@@ -113,46 +231,48 @@
         String path = getPath(serviceName, Constants.CONDITION_ROUTE);
         String config = dynamicConfiguration.getConfig(path);
         if (config != null) {
-            ConditionRouteDTO conditionRoute = YamlParser.loadObject(config, ConditionRouteDTO.class);
+            RoutingRuleDTO routeRule = YamlParser.loadObject(config, RoutingRuleDTO.class);
 
-            if (conditionRoute.getScope().equals("service")) {
+            if (routeRule.getScope().equals(Constants.SERVICE)) {
                 //for 2.6
-                URL oldURL = convertRouteToOldRoute(conditionRoute).toUrl().addParameter(Constants.COMPATIBLE_CONFIG,true);
+                URL oldURL = convertRouteToOldRoute(RouteRule.createConditionRouteFromRule(routeRule)).toUrl().addParameter(Constants.COMPATIBLE_CONFIG,true);
                 registry.unregister(oldURL);
                 oldURL = oldURL.addParameter("enabled", false);
                 registry.register(oldURL);
             }
 
             //2.7
-            conditionRoute.setEnabled(false);
-            dynamicConfiguration.setConfig(path, YamlParser.dumpObject(conditionRoute));
+            routeRule.setEnabled(false);
+            dynamicConfiguration.setConfig(path, YamlParser.dumpObject(routeRule));
         }
 
     }
 
     @Override
-    public ConditionRouteDTO findConditionRoute(String serviceName) {
-        String path = getPath(serviceName, Constants.CONDITION_ROUTE);
+    public ConditionRouteDTO findConditionRoute(String id) {
+        String path = getPath(id, Constants.CONDITION_ROUTE);
         String config = dynamicConfiguration.getConfig(path);
         if (config != null) {
-            return YamlParser.loadObject(config, ConditionRouteDTO.class);
+            RoutingRuleDTO routingRuleDTO = YamlParser.loadObject(config, RoutingRuleDTO.class);
+            ConditionRouteDTO conditionRouteDTO = RouteRule.createConditionRouteFromRule(routingRuleDTO);
+            return conditionRouteDTO;
         }
         return null;
     }
 
     @Override
     public void createTagRoute(TagRouteDTO tagRoute) {
-        tagRoute = convertTagRouteDTOtoStore(tagRoute);
-        String path = getPath(tagRoute.getKey(),Constants.TAG_ROUTE);
+        String id = ConvertUtil.getIdFromDTO(tagRoute);
+        String path = getPath(id,Constants.TAG_ROUTE);
         dynamicConfiguration.setConfig(path, YamlParser.dumpObject(tagRoute));
     }
 
     @Override
     public void updateTagRoute(TagRouteDTO tagRoute) {
-        tagRoute = convertTagRouteDTOtoStore(tagRoute);
-        String path = getPath(tagRoute.getKey(), Constants.TAG_ROUTE);
+        String id = ConvertUtil.getIdFromDTO(tagRoute);
+        String path = getPath(id, Constants.TAG_ROUTE);
         if (dynamicConfiguration.getConfig(path) == null) {
-            throw new ResourceNotFoundException("can not find tagroute: " + tagRoute.getKey());
+            throw new ResourceNotFoundException("can not find tagroute: " + id);
             //throw exception
         }
         dynamicConfiguration.setConfig(path, YamlParser.dumpObject(tagRoute));
@@ -207,7 +327,7 @@
         }
     }
 
-    private String parseCondition(String[] conditions) {
+    private String parseCondition(List<String> conditions) {
         StringBuilder when = new StringBuilder();
         StringBuilder then = new StringBuilder();
         for (String condition : conditions) {
@@ -237,7 +357,7 @@
 
     private Route convertRouteToOldRoute(ConditionRouteDTO route) {
         Route old = new Route();
-        old.setService(route.getKey());
+        old.setService(route.getService());
         old.setEnabled(route.isEnabled());
         old.setForce(route.isForce());
         old.setRuntime(route.isRuntime());
@@ -246,24 +366,4 @@
         old.setRule(rule);
         return old;
     }
-
-    private ConditionRouteDTO convertRouteDTOtoStore(ConditionRouteDTO conditionRoute) {
-        if (StringUtils.isNoneEmpty(conditionRoute.getApplication())) {
-            conditionRoute.setScope("application");
-            conditionRoute.setKey(conditionRoute.getApplication());
-            conditionRoute.setApplication(null);
-        } else {
-            conditionRoute.setScope("service");
-            conditionRoute.setKey(conditionRoute.getService());
-            conditionRoute.setService(null);
-        }
-        return conditionRoute;
-    }
-
-    private TagRouteDTO convertTagRouteDTOtoStore(TagRouteDTO tagRouteDTO) {
-        tagRouteDTO.setKey(tagRouteDTO.getApplication());
-        tagRouteDTO.setScope("application");
-        tagRouteDTO.setApplication(null);
-        return tagRouteDTO;
-    }
 }
diff --git a/dubbo-admin-backend/src/test/main/java/org/apache/dubbo/admin/common/util/YamlParserTest.java b/dubbo-admin-backend/src/test/main/java/org/apache/dubbo/admin/common/util/YamlParserTest.java
new file mode 100644
index 0000000..80604d7
--- /dev/null
+++ b/dubbo-admin-backend/src/test/main/java/org/apache/dubbo/admin/common/util/YamlParserTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.dubbo.admin.common.util;
+
+import org.apache.dubbo.admin.model.dto.DynamicConfigDTO;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class YamlParserTest {
+
+    private String streamToString(InputStream stream) {
+        try {
+            byte[] bytes = new byte[stream.available()];
+            stream.read(bytes);
+            return new String(bytes);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Test
+    public void parseLoadBalanceTest() {
+        InputStream yamlStream = this.getClass().getResourceAsStream("/LoadBalance.yml");
+        DynamicConfigDTO overrideDTO = YamlParser.loadObject(streamToString(yamlStream), DynamicConfigDTO.class);
+        if ("weight".equals(null)) {
+            System.out.println("aa");
+        }
+        overrideDTO.getConfigs();
+    }
+
+
+}
diff --git a/dubbo-admin-backend/src/test/main/resources/LoadBalance.yml b/dubbo-admin-backend/src/test/main/resources/LoadBalance.yml
new file mode 100644
index 0000000..bbf1742
--- /dev/null
+++ b/dubbo-admin-backend/src/test/main/resources/LoadBalance.yml
@@ -0,0 +1,15 @@
+---
+apiVersion: v2.7
+scope: application
+key: governance-consumer
+enabled: false
+configs:
+  - addresses: ["0.0.0.0:20880"]
+    side: provider
+    parameters:
+      timeout: 2000
+  - type: balancing
+    enabled: true
+    parameters:
+      method: '*'
+      strategy: random
diff --git a/dubbo-admin-frontend/src/components/governance/AccessControl.vue b/dubbo-admin-frontend/src/components/governance/AccessControl.vue
index 445c448..baa7422 100644
--- a/dubbo-admin-frontend/src/components/governance/AccessControl.vue
+++ b/dubbo-admin-frontend/src/components/governance/AccessControl.vue
@@ -20,10 +20,40 @@
                fluid>
     <v-layout row
               wrap>
-      <v-flex xs12>
-        <search v-model="filter"
-                :submit="search"
-                label="Search Access Control by service name"></search>
+      <v-flex lg12>
+        <v-card flat color="transparent">
+          <v-card-text>
+            <v-form>
+              <v-layout row wrap>
+                <v-combobox
+                  id="serviceSearch"
+                  v-model="filter"
+                  flat
+                  append-icon=""
+                  hide-no-data
+                  :suffix="queryBy"
+                  label="Search Routing Rule"
+                ></v-combobox>
+                <v-menu class="hidden-xs-only">
+                  <v-btn slot="activator" large icon>
+                    <v-icon>unfold_more</v-icon>
+                  </v-btn>
+
+                  <v-list>
+                    <v-list-tile
+                      v-for="(item, i) in items"
+                      :key="i"
+                      @click="selected = i">
+                      <v-list-tile-title>{{ item.title }}</v-list-tile-title>
+                    </v-list-tile>
+                  </v-list>
+                </v-menu>
+                <v-btn @click="search" color="primary" large>Search</v-btn>
+
+              </v-layout>
+            </v-form>
+          </v-card-text>
+        </v-card>
       </v-flex>
     </v-layout>
 
@@ -42,9 +72,8 @@
                  class="mb-2">CREATE</v-btn>
         </v-toolbar>
 
-        <v-card-text class="pa-0">
-          <v-data-table v-model="selected"
-                        :headers="headers"
+        <v-card-text class="pa-0" v-if="selected == 0">
+          <v-data-table :headers="serviceHeaders"
                         :items="accesses"
                         :loading="loading"
                         hide-actions
@@ -73,6 +102,36 @@
             </template>
           </v-data-table>
         </v-card-text>
+        <v-card-text class="pa-0" v-if="selected == 1">
+          <v-data-table :headers="appHeaders"
+                        :items="accesses"
+                        :loading="loading"
+                        hide-actions
+                        class="elevation-0">
+            <template slot="items"
+                      slot-scope="props">
+              <td class="text-xs-left">{{ props.item.application }}</td>
+              <td class="text-xs-center px-0">
+                <v-tooltip bottom>
+                  <v-icon small
+                          class="mr-2"
+                          color="blue"
+                          slot="activator"
+                          @click="toEdit(props.item)">edit</v-icon>
+                  <span>Edit</span>
+                </v-tooltip>
+                <v-tooltip bottom>
+                  <v-icon small
+                          class="mr-2"
+                          slot="activator"
+                          color="red"
+                          @click="toDelete(props.item)">delete</v-icon>
+                  <span>Delete</span>
+                </v-tooltip>
+              </td>
+            </template>
+          </v-data-table>
+        </v-card-text>
       </v-card>
     </v-flex>
 
@@ -140,10 +199,14 @@
 export default {
   name: 'AccessControl',
   data: () => ({
-    selected: [],
+    items: [
+      {id: 0, title: 'service name', value: 'serviceName'},
+      {id: 1, title: 'application', value: 'application'}
+    ],
+    selected: 0,
     filter: null,
     loading: false,
-    headers: [
+    serviceHeaders: [
       {
         text: 'Service Name',
         value: 'service',
@@ -156,6 +219,19 @@
         width: '115px'
       }
     ],
+    appHeaders: [
+      {
+        text: 'Application Name',
+        value: 'application',
+        align: 'left'
+      },
+      {
+        text: 'Operation',
+        value: 'operation',
+        sortable: false,
+        width: '115px'
+      }
+    ],
     accesses: [],
     required: value => !!value || 'Service ID is required, in form of group/service:version, group and version are optional',
     modal: {
@@ -190,24 +266,30 @@
   methods: {
     search () {
       if (this.filter == null) {
-        this.filter = ''
+        return
       }
+      let type = this.items[this.selected].value
       this.loading = true
-      this.$router.push({
-        path: 'access',
-        query: { service: this.filter }
-      })
-      this.$axios.get('/rules/access', {
-        params: {
-          service: this.filter
-        }
-      }).then(response => {
-        this.accesses = response.data
-        this.loading = false
-      }).catch(error => {
-        this.showSnackbar('error', error.response.data.message)
-        this.loading = false
-      })
+      if (this.selected === 0) {
+        this.$router.push({
+          path: 'access',
+          query: {service: this.filter}
+        })
+      } else if (this.selected === 1) {
+        this.$router.push({
+          path: 'access',
+          query: {application: this.filter}
+        })
+      }
+      let url = '/rules/access/?' + type + '=' + this.filter
+      this.$axios.get(url)
+        .then(response => {
+          this.accesses = response.data
+          this.loading = false
+        }).catch(error => {
+          this.showSnackbar('error', error.response.data.message)
+          this.loading = false
+        })
     },
     closeModal () {
       this.modal.enable = false
@@ -226,47 +308,84 @@
     createItem () {
       let doc = yaml.load(this.modal.content)
       this.filter = ''
-      if (this.modal.service === '' || this.modal.service === null) {
+      if (this.modal.service === '' && this.modal.service === null) {
         return
       }
+      var vm = this
       this.$axios.post('/rules/access', {
         service: this.modal.service,
+        application: this.modal.application,
         whitelist: doc.whitelist,
         blacklist: doc.blacklist
       }).then(response => {
-        this.closeModal()
-        this.search(this.filter)
+        if (response.status === 201) {
+          if (vm.modal.service !== null) {
+            vm.selected = 0
+            vm.filter = vm.modal.service
+          } else {
+            vm.selected = 1
+            vm.filter = vm.modal.application
+          }
+          this.search()
+          this.closeModal()
+        }
         this.showSnackbar('success', 'Create success')
       }).catch(error => this.showSnackbar('error', error.response.data.message))
     },
     toEdit (item) {
+      let itemId = null
+      if (this.selected === 0) {
+        itemId = item.service
+      } else {
+        itemId = item.application
+      }
       Object.assign(this.modal, {
         enable: true,
         title: 'Edit',
         saveBtn: 'Update',
         click: this.editItem,
-        id: item.id,
+        id: itemId,
         service: item.service,
+        application: item.application,
         content: yaml.safeDump({blacklist: item.blacklist, whitelist: item.whitelist})
       })
     },
     editItem () {
       let doc = yaml.load(this.modal.content)
+      let vm = this
       this.$axios.put('/rules/access/' + this.modal.id, {
         whitelist: doc.whitelist,
-        blacklist: doc.blacklist
+        blacklist: doc.blacklist,
+        application: this.modal.application,
+        service: this.modal.service
+
       }).then(response => {
-        this.closeModal()
-        this.search(this.filter)
+        if (response.status === 200) {
+          if (vm.modal.service !== null) {
+            vm.selected = 0
+            vm.filter = vm.modal.service
+          } else {
+            vm.selected = 1
+            vm.filter = vm.modal.application
+          }
+          vm.closeModal()
+          vm.search()
+        }
         this.showSnackbar('success', 'Update success')
       }).catch(error => this.showSnackbar('error', error.response.data.message))
     },
     toDelete (item) {
+      let itemId = null
+      if (this.selected === 0) {
+        itemId = item.service
+      } else {
+        itemId = item.application
+      }
       Object.assign(this.confirm, {
         enable: true,
         title: 'Are you sure to Delete Access Control',
-        text: `Service: ${item.service}`,
-        id: item.id
+        text: `Id: ${itemId}`,
+        id: itemId
       })
     },
     deleteItem (id) {
@@ -279,15 +398,24 @@
     showSnackbar (color, message) {
       this.$notify(message, color)
       this.confirm.enable = false
-      this.selected = []
+    }
+  },
+  computed: {
+    queryBy () {
+      return 'by ' + this.items[this.selected].title
     }
   },
   mounted () {
-    let query = this.$conditionRoute.query
+    let query = this.$route.query
     if ('service' in query) {
       this.filter = query['service']
-      this.search()
+      this.selected = 0
     }
+    if ('application' in query) {
+      this.filter = query['application']
+      this.selected = 1
+    }
+    this.search()
   },
   components: {
     AceEditor,
diff --git a/dubbo-admin-frontend/src/components/governance/LoadBalance.vue b/dubbo-admin-frontend/src/components/governance/LoadBalance.vue
index 8b5b7a3..db0e1ee 100644
--- a/dubbo-admin-frontend/src/components/governance/LoadBalance.vue
+++ b/dubbo-admin-frontend/src/components/governance/LoadBalance.vue
@@ -18,9 +18,40 @@
 <template>
   <v-container grid-list-xl fluid >
     <v-layout row wrap>
-      <v-flex xs12 >
-        <search v-model="filter" :submit="submit" label="Search Load Balance by service Name"></search>
+      <v-flex lg12>
+        <v-card flat color="transparent">
+          <v-card-text>
+            <v-form>
+              <v-layout row wrap>
+                <v-combobox
+                  id="serviceSearch"
+                  v-model="filter"
+                  flat
+                  append-icon=""
+                  hide-no-data
+                  :suffix="queryBy"
+                  label="Search Balancing Rule"
+                ></v-combobox>
+                <v-menu class="hidden-xs-only">
+                  <v-btn slot="activator" large icon>
+                    <v-icon>unfold_more</v-icon>
+                  </v-btn>
 
+                  <v-list>
+                    <v-list-tile
+                      v-for="(item, i) in items"
+                      :key="i"
+                      @click="selected = i">
+                      <v-list-tile-title>{{ item.title }}</v-list-tile-title>
+                    </v-list-tile>
+                  </v-list>
+                </v-menu>
+                <v-btn @click="submit" color="primary" large>Search</v-btn>
+
+              </v-layout>
+            </v-form>
+          </v-card-text>
+        </v-card>
       </v-flex>
     </v-layout>
 
@@ -32,9 +63,9 @@
           <v-btn outline color="primary" @click.stop="openDialog" class="mb-2">CREATE</v-btn>
         </v-toolbar>
 
-        <v-card-text class="pa-0">
+        <v-card-text class="pa-0" v-if="selected == 0">
           <v-data-table
-            :headers="headers"
+            :headers="serviceHeaders"
             :items="loadBalances"
             hide-actions
             class="elevation-0"
@@ -53,6 +84,28 @@
             </template>
           </v-data-table>
         </v-card-text>
+
+        <v-card-text class="pa-0" v-if="selected == 1">
+          <v-data-table
+            :headers="appHeaders"
+            :items="loadBalances"
+            hide-actions
+            class="elevation-0"
+          >
+            <template slot="items" slot-scope="props">
+              <td class="text-xs-left">{{ props.item.application }}</td>
+              <td class="text-xs-left">{{ props.item.methodName }}</td>
+              <td class="text-xs-center px-0">
+                <v-tooltip bottom v-for="op in operations" :key="op.id">
+                  <v-icon small class="mr-2" slot="activator" @click="itemOperation(op.icon, props.item)">
+                    {{op.icon}}
+                  </v-icon>
+                  <span>{{op.tooltip}}</span>
+                </v-tooltip>
+              </td>
+            </template>
+          </v-data-table>
+        </v-card-text>
       </v-card>
     </v-flex>
 
@@ -110,6 +163,11 @@
       Search
     },
     data: () => ({
+      items: [
+        {id: 0, title: 'service name', value: 'serviceName'},
+        {id: 1, title: 'application', value: 'application'}
+      ],
+      selected: 0,
       dropdown_font: [ 'Service', 'App', 'IP' ],
       ruleKeys: ['method', 'strategy'],
       pattern: 'Service',
@@ -136,7 +194,7 @@
         'strategy:  # leastactive, random, roundrobin',
       ruleText: '',
       readonly: false,
-      headers: [
+      serviceHeaders: [
         {
           text: 'Service Name',
           value: 'service',
@@ -154,6 +212,25 @@
           sortable: false,
           width: '115px'
         }
+      ],
+      appHeaders: [
+        {
+          text: 'Application Name',
+          value: 'application',
+          align: 'left'
+        },
+        {
+          text: 'Method',
+          value: 'method',
+          align: 'left'
+
+        },
+        {
+          text: 'Operation',
+          value: 'operation',
+          sortable: false,
+          width: '115px'
+        }
       ]
     }),
     methods: {
@@ -161,16 +238,15 @@
         this.search(this.filter, true)
       },
       search: function (filter, rewrite) {
-        this.$axios.get('/rules/balancing', {
-          params: {
-            service: filter
-          }
-        }).then(response => {
-          this.loadBalances = response.data
-          if (rewrite) {
-            this.$router.push({path: 'loadbalance', query: {service: filter}})
-          }
-        })
+        let type = this.items[this.selected].value
+        let url = '/rules/balancing/?' + type + '=' + filter
+        this.$axios.get(url)
+          .then(response => {
+            this.loadBalances = response.data
+            if (rewrite) {
+              this.$router.push({path: 'loadbalance', query: {service: filter}})
+            }
+          })
       },
       closeDialog: function () {
         this.ruleText = this.template
@@ -193,11 +269,13 @@
         this.warn = false
       },
       saveItem: function () {
+        this.ruleText = this.verifyRuleText(this.ruleText)
         let balancing = yaml.safeLoad(this.ruleText)
-        if (this.service === '') {
+        if (this.service === '' && this.application === '') {
           return
         }
         balancing.service = this.service
+        balancing.application = this.application
         if (this.updateId !== '') {
           if (this.updateId === 'close') {
             this.closeDialog()
@@ -206,8 +284,15 @@
             this.$axios.put('/rules/balancing/' + balancing.id, balancing)
               .then(response => {
                 if (response.status === 200) {
-                  this.search(this.service, true)
-                  this.filter = this.service
+                  if (this.service !== '') {
+                    this.selected = 0
+                    this.search(this.service, true)
+                    this.filter = this.service
+                  } else {
+                    this.selected = 1
+                    this.search(this.application, true)
+                    this.filter = this.application
+                  }
                   this.closeDialog()
                   this.$notify.success('Update success')
                 }
@@ -217,8 +302,15 @@
           this.$axios.post('/rules/balancing', balancing)
             .then(response => {
               if (response.status === 201) {
-                this.search(this.service, true)
-                this.filter = this.service
+                if (this.service !== '') {
+                  this.selected = 0
+                  this.search(this.service, true)
+                  this.filter = this.service
+                } else {
+                  this.selected = 1
+                  this.search(this.application, true)
+                  this.filter = this.application
+                }
                 this.closeDialog()
                 this.$notify.success('Create success')
               }
@@ -226,9 +318,15 @@
         }
       },
       itemOperation: function (icon, item) {
+        let itemId = ''
+        if (this.selected === 0) {
+          itemId = item.service
+        } else {
+          itemId = item.application
+        }
         switch (icon) {
           case 'visibility':
-            this.$axios.get('/rules/balancing/' + item.id)
+            this.$axios.get('/rules/balancing/' + itemId)
               .then(response => {
                 let balancing = response.data
                 this.handleBalance(balancing, true)
@@ -236,22 +334,24 @@
               })
             break
           case 'edit':
-            this.$axios.get('/rules/balancing/' + item.id)
+            this.$axios.get('/rules/balancing/' + itemId)
               .then(response => {
                 let balancing = response.data
                 this.handleBalance(balancing, false)
-                this.updateId = item.id
+                this.updateId = itemId
               })
             break
           case 'delete':
-            this.openWarn(' Are you sure to Delete Routing Rule', 'service: ' + item.service)
+            this.openWarn(' Are you sure to Delete Routing Rule', 'service: ' + itemId)
             this.warnStatus.operation = 'delete'
-            this.warnStatus.id = item.id
+            this.warnStatus.id = itemId
         }
       },
       handleBalance: function (balancing, readonly) {
         this.service = balancing.service
+        this.application = balancing.application
         delete balancing.service
+        delete balancing.application
         delete balancing.id
         this.ruleText = yaml.safeDump(balancing)
         this.readonly = readonly
@@ -269,14 +369,29 @@
               this.$notify.success('Delete success')
             }
           })
+      },
+      verifyRuleText: function (ruleText) {
+        let lines = ruleText.split('\n')
+        for (let i = 0; i < lines.length; i++) {
+          if (lines[i].includes('methodName') && lines[i].includes('*')) {
+            lines[i] = "methodName: '*'"
+          }
+        }
+        let newText = lines.join('\n')
+        return newText
       }
     },
     created () {
       this.setHeight()
     },
+    computed: {
+      queryBy () {
+        return 'by ' + this.items[this.selected].title
+      }
+    },
     mounted: function () {
       this.ruleText = this.template
-      let query = this.$conditionRoute.query
+      let query = this.$route.query
       let service = null
       Object.keys(query).forEach(function (key) {
         if (key === 'service') {
diff --git a/dubbo-admin-frontend/src/components/governance/Overrides.vue b/dubbo-admin-frontend/src/components/governance/Overrides.vue
index 64c7291..4c1cb0e 100644
--- a/dubbo-admin-frontend/src/components/governance/Overrides.vue
+++ b/dubbo-admin-frontend/src/components/governance/Overrides.vue
@@ -193,7 +193,7 @@
         'force: true\n' +
         'configs: \n' +
         '  - addresses: [0.0.0.0]  # 0.0.0.0 for all addresses\n' +
-        '    side: consumer        # effective side, consumer or provider\n' +
+        '    side: consumer        # effective side, consumer or addresses\n' +
         '    parameters: \n' +
         '      timeout: 6000       # dynamic config parameter\n',
       ruleText: '',
diff --git a/dubbo-admin-frontend/src/components/governance/RoutingRule.vue b/dubbo-admin-frontend/src/components/governance/RoutingRule.vue
index f4663cf..23103a6 100644
--- a/dubbo-admin-frontend/src/components/governance/RoutingRule.vue
+++ b/dubbo-admin-frontend/src/components/governance/RoutingRule.vue
@@ -17,43 +17,43 @@
 
 <template>
   <v-container grid-list-xl fluid >
-      <v-layout row wrap>
-        <v-flex lg12>
-          <v-card flat color="transparent">
-            <v-card-text>
-              <v-form>
-                <v-layout row wrap>
-                  <v-combobox
-                    id="serviceSearch"
-                    v-model="filter"
-                    flat
-                    append-icon=""
-                    hide-no-data
-                    :suffix="queryBy"
-                    label="Search Routing Rule"
-                  ></v-combobox>
-                  <v-menu class="hidden-xs-only">
-                    <v-btn slot="activator" large icon>
-                      <v-icon>unfold_more</v-icon>
-                    </v-btn>
+    <v-layout row wrap>
+      <v-flex lg12>
+        <v-card flat color="transparent">
+          <v-card-text>
+            <v-form>
+              <v-layout row wrap>
+                <v-combobox
+                  id="serviceSearch"
+                  v-model="filter"
+                  flat
+                  append-icon=""
+                  hide-no-data
+                  :suffix="queryBy"
+                  label="Search Routing Rule"
+                ></v-combobox>
+                <v-menu class="hidden-xs-only">
+                  <v-btn slot="activator" large icon>
+                    <v-icon>unfold_more</v-icon>
+                  </v-btn>
 
-                    <v-list>
-                      <v-list-tile
-                        v-for="(item, i) in items"
-                        :key="i"
-                        @click="selected = i">
-                        <v-list-tile-title>{{ item.title }}</v-list-tile-title>
-                      </v-list-tile>
-                    </v-list>
-                  </v-menu>
-                  <v-btn @click="submit" color="primary" large>Search</v-btn>
+                  <v-list>
+                    <v-list-tile
+                      v-for="(item, i) in items"
+                      :key="i"
+                      @click="selected = i">
+                      <v-list-tile-title>{{ item.title }}</v-list-tile-title>
+                    </v-list-tile>
+                  </v-list>
+                </v-menu>
+                <v-btn @click="submit" color="primary" large>Search</v-btn>
 
-                </v-layout>
-              </v-form>
-            </v-card-text>
-          </v-card>
-        </v-flex>
-      </v-layout>
+              </v-layout>
+            </v-form>
+          </v-card-text>
+        </v-card>
+      </v-flex>
+    </v-layout>
     <v-flex lg12>
       <v-card>
         <v-toolbar flat color="transparent" class="elevation-0">
@@ -361,8 +361,6 @@
               })
             break
           case 'edit':
-            let id = {}
-            id.id = itemId
             this.$axios.get('/rules/route/condition/' + itemId)
               .then(response => {
                 let conditionRoute = response.data
@@ -371,17 +369,17 @@
               })
             break
           case 'block':
-            this.openWarn(' Are you sure to block Routing Rule', 'service: ' + item.service)
+            this.openWarn(' Are you sure to block Routing Rule', 'service: ' + itemId)
             this.warnStatus.operation = 'disable'
             this.warnStatus.id = itemId
             break
           case 'check_circle_outline':
-            this.openWarn(' Are you sure to enable Routing Rule', 'service: ' + item.service)
+            this.openWarn(' Are you sure to enable Routing Rule', 'service: ' + itemId)
             this.warnStatus.operation = 'enable'
             this.warnStatus.id = itemId
             break
           case 'delete':
-            this.openWarn(' Are you sure to Delete Routing Rule', 'service: ' + item.service)
+            this.openWarn(' Are you sure to Delete Routing Rule', 'service: ' + itemId)
             this.warnStatus.operation = 'delete'
             this.warnStatus.id = itemId
         }
diff --git a/dubbo-admin-frontend/src/components/governance/WeightAdjust.vue b/dubbo-admin-frontend/src/components/governance/WeightAdjust.vue
index e936bb8..f1514a9 100644
--- a/dubbo-admin-frontend/src/components/governance/WeightAdjust.vue
+++ b/dubbo-admin-frontend/src/components/governance/WeightAdjust.vue
@@ -18,9 +18,40 @@
 <template>
   <v-container grid-list-xl fluid >
     <v-layout row wrap>
-      <v-flex xs12 >
-        <search v-model="filter" :submit="submit" label="Search Weight by service name"></search>
+      <v-flex lg12>
+        <v-card flat color="transparent">
+          <v-card-text>
+            <v-form>
+              <v-layout row wrap>
+                <v-combobox
+                  id="serviceSearch"
+                  v-model="filter"
+                  flat
+                  append-icon=""
+                  hide-no-data
+                  :suffix="queryBy"
+                  label="Search Routing Rule"
+                ></v-combobox>
+                <v-menu class="hidden-xs-only">
+                  <v-btn slot="activator" large icon>
+                    <v-icon>unfold_more</v-icon>
+                  </v-btn>
 
+                  <v-list>
+                    <v-list-tile
+                      v-for="(item, i) in items"
+                      :key="i"
+                      @click="selected = i">
+                      <v-list-tile-title>{{ item.title }}</v-list-tile-title>
+                    </v-list-tile>
+                  </v-list>
+                </v-menu>
+                <v-btn @click="submit" color="primary" large>Search</v-btn>
+
+              </v-layout>
+            </v-form>
+          </v-card-text>
+        </v-card>
       </v-flex>
     </v-layout>
 
@@ -32,9 +63,9 @@
           <v-btn outline color="primary" @click.stop="openDialog" class="mb-2">CREATE</v-btn>
         </v-toolbar>
 
-        <v-card-text class="pa-0">
+        <v-card-text class="pa-0" v-if="selected == 0">
           <v-data-table
-            :headers="headers"
+            :headers="serviceHeaders"
             :items="weights"
             hide-actions
             class="elevation-0"
@@ -53,6 +84,27 @@
             </template>
           </v-data-table>
         </v-card-text>
+        <v-card-text class="pa-0" v-if="selected == 1">
+          <v-data-table
+            :headers="appHeaders"
+            :items="weights"
+            hide-actions
+            class="elevation-0"
+          >
+            <template slot="items" slot-scope="props">
+              <td class="text-xs-left">{{ props.item.application }}</td>
+              <td class="text-xs-left">{{ props.item.method }}</td>
+              <td class="text-xs-center px-0">
+                <v-tooltip bottom v-for="op in operations" :key="op.id">
+                  <v-icon small class="mr-2" slot="activator" @click="itemOperation(op.icon, props.item)">
+                    {{op.icon}}
+                  </v-icon>
+                  <span>{{op.tooltip}}</span>
+                </v-tooltip>
+              </td>
+            </template>
+          </v-data-table>
+        </v-card-text>
       </v-card>
     </v-flex>
 
@@ -111,6 +163,11 @@
       Search
     },
     data: () => ({
+      items: [
+        {id: 0, title: 'service name', value: 'serviceName'},
+        {id: 1, title: 'application', value: 'application'}
+      ],
+      selected: 0,
       dropdown_font: [ 'Service', 'App', 'IP' ],
       ruleKeys: ['weight', 'address'],
       pattern: 'Service',
@@ -134,12 +191,12 @@
       required: value => !!value || 'Service ID is required, in form of group/service:version, group and version are optional',
       template:
         'weight: 100  # 100 for default\n' +
-        'provider:   # provider\'s ip\n' +
+        'addresses:   # addresses\'s ip\n' +
         '  - 192.168.0.1\n' +
         '  - 192.168.0.2',
       ruleText: '',
       readonly: false,
-      headers: [
+      serviceHeaders: [
         {
           text: 'Service Name',
           value: 'service',
@@ -157,6 +214,25 @@
           sortable: false,
           width: '115px'
         }
+      ],
+      appHeaders: [
+        {
+          text: 'Application Name',
+          value: 'application',
+          align: 'left'
+        },
+        {
+          text: 'Weight',
+          value: 'weight',
+          align: 'left'
+
+        },
+        {
+          text: 'Operation',
+          value: 'operation',
+          sortable: false,
+          width: '115px'
+        }
       ]
     }),
     methods: {
@@ -164,16 +240,19 @@
         this.search(this.filter, true)
       },
       search: function (filter, rewrite) {
-        this.$axios.get('/rules/weight/', {
-          params: {
-            service: filter
-          }
-        }).then(response => {
-          this.weights = response.data
-          if (rewrite) {
-            this.$router.push({path: 'weight', query: {service: filter}})
-          }
-        })
+        let type = this.items[this.selected].value
+        let url = '/rules/weight/?' + type + '=' + filter
+        this.$axios.get(url)
+          .then(response => {
+            this.weights = response.data
+            if (rewrite) {
+              if (this.selected === 0) {
+                this.$router.push({path: 'weight', query: {serviceName: filter}})
+              } else if (this.selected === 1) {
+                this.$router.push({path: 'weight', query: {application: filter}})
+              }
+            }
+          })
       },
       closeDialog: function () {
         this.ruleText = this.template
@@ -196,10 +275,11 @@
       },
       saveItem: function () {
         let weight = yaml.safeLoad(this.ruleText)
-        if (this.service === '') {
+        if (this.service === '' && this.application === '') {
           return
         }
         weight.service = this.service
+        weight.application = this.application
         if (this.updateId !== '') {
           if (this.updateId === 'close') {
             this.closeDialog()
@@ -208,8 +288,15 @@
             this.$axios.put('/rules/weight/' + weight.id, weight)
               .then(response => {
                 if (response.status === 200) {
-                  this.search(this.service, true)
-                  this.filter = this.service
+                  if (this.service !== '') {
+                    this.selected = 0
+                    this.search(this.service, true)
+                    this.filter = this.service
+                  } else {
+                    this.selected = 1
+                    this.search(this.application, true)
+                    this.filter = this.application
+                  }
                   this.closeDialog()
                   this.$notify.success('Update success')
                 }
@@ -218,9 +305,16 @@
         } else {
           this.$axios.post('/rules/weight', weight)
             .then(response => {
-              if (response.status === 200) {
-                this.search(this.service, true)
-                this.filter = this.service
+              if (response.status === 201) {
+                if (this.service !== '') {
+                  this.selected = 0
+                  this.search(this.service, true)
+                  this.filter = this.service
+                } else {
+                  this.selected = 1
+                  this.search(this.application, true)
+                  this.filter = this.application
+                }
                 this.closeDialog()
                 this.$notify.success('Create success')
               }
@@ -228,9 +322,15 @@
         }
       },
       itemOperation: function (icon, item) {
+        let itemId = ''
+        if (this.selected === 0) {
+          itemId = item.service
+        } else {
+          itemId = item.application
+        }
         switch (icon) {
           case 'visibility':
-            this.$axios.get('/rules/weight/' + item.id)
+            this.$axios.get('/rules/weight/' + itemId)
                 .then(response => {
                   let weight = response.data
                   this.handleWeight(weight, true)
@@ -238,22 +338,24 @@
                 })
             break
           case 'edit':
-            this.$axios.get('/rules/weight/' + item.id)
+            this.$axios.get('/rules/weight/' + itemId)
                 .then(response => {
                   let weight = response.data
                   this.handleWeight(weight, false)
-                  this.updateId = item.id
+                  this.updateId = itemId
                 })
             break
           case 'delete':
-            this.openWarn(' Are you sure to Delete Routing Rule', 'service: ' + item.service)
+            this.openWarn(' Are you sure to Delete Routing Rule', 'service: ' + itemId)
             this.warnStatus.operation = 'delete'
-            this.warnStatus.id = item.id
+            this.warnStatus.id = itemId
         }
       },
       handleWeight: function (weight, readonly) {
         this.service = weight.service
+        this.application = weight.application
         delete weight.service
+        delete weight.application
         this.ruleText = yaml.safeDump(weight)
         this.readonly = readonly
         this.dialog = true
@@ -275,9 +377,14 @@
     created () {
       this.setHeight()
     },
+    computed: {
+      queryBy () {
+        return 'by ' + this.items[this.selected].title
+      }
+    },
     mounted: function () {
       this.ruleText = this.template
-      let query = this.$conditionRoute.query
+      let query = this.$route.query
       let service = null
       Object.keys(query).forEach(function (key) {
         if (key === 'service') {