blackwhite in condition route (#776)

* modify whiteblack

* route support delete blackwhite

* remove useless code and english comment

* whiteblacklist key modify

* whiteblacklist key modify

Co-authored-by: 羽铭 <xing.xyy@alibaba-inc.com>
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/RouteUtils.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/RouteUtils.java
index 1e502eb..40ee18d 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/RouteUtils.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/RouteUtils.java
@@ -287,12 +287,46 @@
         return result;
     }
 
+    /**
+     * the function of "black white" is part of the function of condition route
+     * @param conditions
+     * @return
+     */
+    public static List<String> filterConditionsExcludeBlackWhiteList(List<String> conditions) {
+        List<String> result = new ArrayList<>();
+        if (conditions == null || conditions.isEmpty()) {
+            return result;
+        }
+        for (String condition : conditions) {
+            if (!isBlackList(condition) && !isWhiteList(condition)) {
+                result.add(condition);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * the function of "black white" is part of the function of condition route
+     * @param conditions
+     * @return
+     */
     public static List<String> filterConditionRuleFromConditions(List<String> conditions) {
         List<String> result = new ArrayList<>();
         if (conditions == null || conditions.isEmpty()) {
             return result;
         }
         for (String condition : conditions) {
+            result.add(condition);
+        }
+        return result;
+    }
+
+    public static List<String> removeBlackWhiteListRuleFromConditions(List<String> conditions) {
+        List<String> result = new ArrayList<>();
+        if (conditions == null || conditions.isEmpty()) {
+            return result;
+        }
+        for (String condition : conditions) {
             if (!isBlackList(condition) && !isWhiteList(condition)) {
                 result.add(condition);
             }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Route.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Route.java
index c03980a..b80c61b 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Route.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Route.java
@@ -214,8 +214,8 @@
         String interfaze = Tool.getInterface(service);
         return URL.valueOf(Constants.ROUTE_PROTOCOL + "://" + Constants.ANYHOST_VALUE + "/" + interfaze
                 + "?" + Constants.CATEGORY_KEY + "=" + Constants.ROUTERS_CATEGORY
-                + "&router=condition&runtime=" + isRuntime() + "&enabled=" + isEnabled() + "&priority=" + getPriority() + "&force=" + isForce() + "&dynamic=" + isDynamic()
-                + "&name=" + getName() + "&" + Constants.RULE_KEY + "=" + URL.encode(getMatchRule() + " => " + getFilterRule())
+                + "&router=condition&runtime=" + isRuntime() + "&enabled=" + isEnabled() + "&priority=" + getPriority() + "&force=" + (getMatchRule().contains("host") ? "true" : isForce()) + "&dynamic=" + isDynamic()
+                + "&name=" + getName() + "&" + Constants.RULE_KEY + "=" + URL.encode(getMatchRule() + " => " + (getMatchRule().contains("host") ? "false" : getFilterRule()))
                 + (group == null ? "" : "&" + Constants.GROUP_KEY + "=" + group)
                 + (version == null ? "" : "&" + Constants.VERSION_KEY + "=" + version));
     }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java
index 788c7d3..a9d3b1b 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/RouteServiceImpl.java
@@ -29,6 +29,7 @@
 import org.apache.dubbo.admin.model.store.TagRoute;
 import org.apache.dubbo.admin.service.RouteService;
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.springframework.stereotype.Component;
 
@@ -95,20 +96,19 @@
             //throw exception
         }
         RoutingRule route = YamlParser.loadObject(config, RoutingRule.class);
-        List<String> blackWhiteList = RouteUtils.filterBlackWhiteListFromConditions(route.getConditions());
-        if (blackWhiteList.size() != 0) {
-           route.setConditions(blackWhiteList);
-            dynamicConfiguration.setConfig(path, YamlParser.dumpObject(route));
-        } else {
-            dynamicConfiguration.deleteConfig(path);
-        }
+        dynamicConfiguration.deleteConfig(path);
 
         //for 2.6
         if (Constants.SERVICE.equals(route.getScope())) {
             RoutingRule originRule = YamlParser.loadObject(config, RoutingRule.class);
             ConditionRouteDTO conditionRouteDTO = RouteUtils.createConditionRouteFromRule(originRule);
             for (Route old : convertRouteToOldRoute(conditionRouteDTO)) {
-            	registry.unregister(old.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
+                URL oldUrl = old.toUrl();
+                if(oldUrl.getParameter("rule").contains("host") && oldUrl.getParameter("rule").contains("false")) {
+                    registry.unregister(oldUrl);
+                } else {
+                    registry.unregister(oldUrl.addParameter(Constants.COMPATIBLE_CONFIG, true));
+                }
             }
         }
     }
@@ -120,7 +120,7 @@
         if (config != null) {
             RoutingRule ruleDTO = YamlParser.loadObject(config, RoutingRule.class);
             List<String> blackWhiteList = RouteUtils.filterBlackWhiteListFromConditions(ruleDTO.getConditions());
-            List<String> conditions = RouteUtils.filterConditionRuleFromConditions(ruleDTO.getConditions());
+            List<String> conditions = RouteUtils.removeBlackWhiteListRuleFromConditions(ruleDTO.getConditions());
             if (conditions.size() == 0) {
                 dynamicConfiguration.deleteConfig(path);
             } else {
@@ -146,11 +146,12 @@
             ruleDTO = new RoutingRule();
             ruleDTO.setEnabled(true);
             if (StringUtils.isNoneEmpty(accessDTO.getApplication())) {
+                ruleDTO.setKey(accessDTO.getApplication());
                 ruleDTO.setScope(Constants.APPLICATION);
             } else {
+                ruleDTO.setKey(accessDTO.getService().replace("/", "*"));
                 ruleDTO.setScope(Constants.SERVICE);
             }
-            ruleDTO.setKey(id);
             ruleDTO.setConditions(blackWhiteList);
         } else {
             ruleDTO = YamlParser.loadObject(config, RoutingRule.class);
@@ -177,12 +178,14 @@
         if (config != null) {
             RoutingRule ruleDTO = YamlParser.loadObject(config, RoutingRule.class);
             List<String> blackWhiteList = RouteUtils.filterBlackWhiteListFromConditions(ruleDTO.getConditions());
-            AccessDTO accessDTO = RouteUtils.convertToAccessDTO(blackWhiteList, ruleDTO.getScope(), ruleDTO.getKey());
-            accessDTO.setId(id);
-            if (Constants.SERVICE.equals(ruleDTO.getScope())) {
-                ConvertUtil.detachIdToService(id, accessDTO);
+            if(CollectionUtils.isNotEmpty(blackWhiteList)) {
+                AccessDTO accessDTO = RouteUtils.convertToAccessDTO(blackWhiteList, ruleDTO.getScope(), ruleDTO.getKey());
+                accessDTO.setId(id);
+                if (Constants.SERVICE.equals(ruleDTO.getScope())) {
+                    ConvertUtil.detachIdToService(id, accessDTO);
+                }
+                return accessDTO;
             }
-            return accessDTO;
         }
         return null;
     }
@@ -197,7 +200,7 @@
         if (config != null) {
             RoutingRule ruleDTO = YamlParser.loadObject(config, RoutingRule.class);
             oldList = RouteUtils.filterBlackWhiteListFromConditions(ruleDTO.getConditions());
-            List<String> conditions = RouteUtils.filterConditionRuleFromConditions(ruleDTO.getConditions());
+            List<String> conditions = RouteUtils.filterConditionsExcludeBlackWhiteList(ruleDTO.getConditions());
             conditions.addAll(blackWhiteList);
             ruleDTO.setConditions(conditions);
             dynamicConfiguration.setConfig(path, YamlParser.dumpObject(ruleDTO));
@@ -274,6 +277,9 @@
         if (config != null) {
             RoutingRule routingRule = YamlParser.loadObject(config, RoutingRule.class);
             ConditionRouteDTO conditionRouteDTO = RouteUtils.createConditionRouteFromRule(routingRule);
+            if(null == conditionRouteDTO || CollectionUtils.isEmpty(conditionRouteDTO.getConditions())) {
+                return null;
+            }
             String service = conditionRouteDTO.getService();
             if (org.apache.commons.lang3.StringUtils.isNotBlank(service)) {
                 conditionRouteDTO.setService(service.replace("*", "/"));