Skip to content

Commit

Permalink
增加基于Spel表达式的条件路由
Browse files Browse the repository at this point in the history
  • Loading branch information
HaojunRen committed Jan 6, 2020
1 parent 9e64646 commit 47e0af8
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public class DiscoveryConstant {
public static final String DEFAULT = "default";
public static final String UNKNOWN = "unknown";

public static final String EXPRESSION_PREFIX = "H";
public static final String EXPRESSION_REGEX = "\\#" + EXPRESSION_PREFIX + "\\['\\S+'\\]";
public static final String EXPRESSION_SUB_PREFIX = "#" + EXPRESSION_PREFIX + "['";
public static final String EXPRESSION_SUB_SUFFIX = "']";

public static final String DEFAULT_XML_RULE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
"<rule>\r\n" +
"</rule>";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
*/

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
Expand All @@ -23,7 +21,6 @@ public class StrategyConditionEntity implements Serializable {

private String id;
private String conditionHeader;
private Map<String, String> conditionHeaderMap = new LinkedHashMap<String, String>();
private String versionId;
private String regionId;
private String addressId;
Expand All @@ -46,14 +43,6 @@ public void setConditionHeader(String conditionHeader) {
this.conditionHeader = conditionHeader;
}

public Map<String, String> getConditionHeaderMap() {
return conditionHeaderMap;
}

public void setConditionHeaderMap(Map<String, String> conditionHeaderMap) {
this.conditionHeaderMap = conditionHeaderMap;
}

public String getVersionId() {
return versionId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.nepxion.discovery.common.constant.DiscoveryConstant;
import com.nepxion.discovery.common.util.StringUtil;

public class StrategyCustomizationEntity implements Serializable {
private static final long serialVersionUID = 4903833660194433964L;

Expand Down Expand Up @@ -51,9 +54,9 @@ public void setStrategyRouteEntityList(List<StrategyRouteEntity> strategyRouteEn

// Header参数越多,越排在前面
Collections.sort(this.strategyConditionEntityList, new Comparator<StrategyConditionEntity>() {
public int compare(StrategyConditionEntity object1, StrategyConditionEntity object2) {
Integer count1 = object1.getConditionHeaderMap().size();
Integer count2 = object2.getConditionHeaderMap().size();
public int compare(StrategyConditionEntity strategyConditionEntity1, StrategyConditionEntity strategyConditionEntity2) {
Integer count1 = StringUtil.count(strategyConditionEntity1.getConditionHeader(), DiscoveryConstant.EXPRESSION_SUB_PREFIX);
Integer count2 = StringUtil.count(strategyConditionEntity2.getConditionHeader(), DiscoveryConstant.EXPRESSION_SUB_PREFIX);

return count2.compareTo(count1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,14 @@ public static String simulateText(int size) {
public static String toDisplaySize(String value) {
return FileUtils.byteCountToDisplaySize(value.length());
}

public static int count(String text, String keyText) {
int count = 0;
while (text.indexOf(keyText) != -1) {
text = text.substring(text.indexOf(keyText) + 1, text.length());
count++;
}

return count;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -687,14 +687,6 @@ private void parseStrategyCondition(Element element, List<StrategyConditionEntit
}
String header = headerAttribute.getData().toString().trim();
strategyConditionEntity.setConditionHeader(header);
List<String> headerList = StringUtil.splitToList(header, DiscoveryConstant.SEPARATE);
for (String value : headerList) {
String[] valueArray = StringUtils.split(value, DiscoveryConstant.EQUALS);
String headerName = valueArray[0].trim();
String headerValue = valueArray[1].trim();

strategyConditionEntity.getConditionHeaderMap().put(headerName, headerValue);
}

Attribute versionIdAttribute = childElement.attribute(ConfigConstant.VERSION_ELEMENT_NAME + DiscoveryConstant.DASH + ConfigConstant.ID_ATTRIBUTE_NAME);
if (versionIdAttribute != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.nepxion.discovery.plugin.framework.util;

/**
* <p>Title: Nepxion Discovery</p>
* <p>Description: Nepxion Discovery</p>
* <p>Copyright: Copyright (c) 2017-2050</p>
* <p>Company: Nepxion</p>
* @author Haojun Ren
* @version 1.0
*/

import java.util.Map;

import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class SpelUtil {
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();

public static boolean eval(String expression, String mapKey, Map<String, String> map) {
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable(mapKey, map);

return eval(expression, context);
}

public static boolean eval(String expression, Map<String, Map<String, String>> map) {
StandardEvaluationContext context = new StandardEvaluationContext();
for (Map.Entry<String, Map<String, String>> entry : map.entrySet()) {
context.setVariable(entry.getKey(), entry.getValue());
}

return eval(expression, context);
}

public static boolean eval(String expression, StandardEvaluationContext context) {
Boolean result = EXPRESSION_PARSER.parseExpression(expression).getValue(context, Boolean.class);

return result != null ? result.booleanValue() : false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.nepxion.discovery.plugin.framework.loadbalance;

/**
* <p>Title: Nepxion Discovery</p>
* <p>Description: Nepxion Discovery</p>
* <p>Copyright: Copyright (c) 2017-2050</p>
* <p>Company: Nepxion</p>
* @author Haojun Ren
* @version 1.0
*/

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import com.nepxion.discovery.common.util.StringUtil;
import com.nepxion.discovery.plugin.framework.util.SpelUtil;

public class SpelTest {
public static void main(String[] args) {
System.out.println(test1());
System.out.println(test2());
System.out.println(test3());
}

private static boolean test1() {
// String expression = "#H['a'] == '123' && #H['b'] == '456'";
// String expression = "#H['a'] == '123' || #H['b'] == '456'";
// String expression = "#H['a'] >= '123' && #H['b'] <= '456'";
// String expression = "#H['a'] >= '123' || #H['b'] <= '456'";
String expression = "#H['a'] != '123' || #H['b'] != '456'";

Map<String, String> headerMap = new HashMap<String, String>();
headerMap.put("a", "123");
headerMap.put("b", "456");

return SpelUtil.eval(expression, "H", headerMap);
}

private static List<String> test2() {
String regex = "\\#H\\['\\S+'\\]";
Pattern pattern = Pattern.compile(regex);

String expression = "#H['a-A'] != '123' || #H['b//SS'] != '456' && #H['C**44!!66'] = 123";
Matcher matcher = pattern.matcher(expression);

List<String> list = new ArrayList<String>();
while (matcher.find()) {
String group = matcher.group();
String value = StringUtils.substringBetween(group, "#H['", "']");
list.add(value);
}

return list;
}

private static int test3() {
String expression = "#H['a-A'] != '123' || #H['b//SS'] != '456' && #H['C**44!!66'] = 123";
String key = "#H['";

return StringUtil.count(expression, key);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,41 @@
* @version 1.0
*/

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import com.nepxion.discovery.common.constant.DiscoveryConstant;
import com.nepxion.discovery.common.entity.StrategyConditionEntity;
import com.nepxion.discovery.plugin.framework.util.SpelUtil;

public class HeaderExpressionStrategyCondition extends AbstractStrategyCondition {
private Pattern pattern = Pattern.compile(DiscoveryConstant.EXPRESSION_REGEX);

@Override
public boolean isTriggered(StrategyConditionEntity strategyConditionEntity) {
// 此为包含若干个Header的表达式
// String conditionHeader = strategyConditionEntity.getConditionHeader();
String conditionHeader = strategyConditionEntity.getConditionHeader();
Map<String, String> headerMap = createHeaderMap(conditionHeader);

return SpelUtil.eval(conditionHeader, DiscoveryConstant.EXPRESSION_PREFIX, headerMap);
}

private Map<String, String> createHeaderMap(String conditionHeader) {
Map<String, String> headerMap = new HashMap<String, String>();

Matcher matcher = pattern.matcher(conditionHeader);
while (matcher.find()) {
String group = matcher.group();
String headerName = StringUtils.substringBetween(group, DiscoveryConstant.EXPRESSION_SUB_PREFIX, DiscoveryConstant.EXPRESSION_SUB_SUFFIX);
String headerValue = strategyContextHolder.getHeader(headerName);
if (StringUtils.isNotBlank(headerValue)) {
headerMap.put(headerName, headerValue);
}
}

// 待实现
return true;
return headerMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.nepxion.discovery.plugin.strategy.condition.HeaderEqualsStrategyCondition;
import com.nepxion.discovery.plugin.strategy.condition.HeaderExpressionStrategyCondition;
import com.nepxion.discovery.plugin.strategy.condition.StrategyCondition;
import com.nepxion.discovery.plugin.strategy.constant.StrategyConstant;
import com.nepxion.discovery.plugin.strategy.isolation.ConsumerIsolationDiscoveryStrategy;
Expand Down Expand Up @@ -64,6 +64,6 @@ public StrategyWrapper strategyWrapper() {
@Bean
@ConditionalOnMissingBean
public StrategyCondition strategyCondition() {
return new HeaderEqualsStrategyCondition();
return new HeaderExpressionStrategyCondition();
}
}
Loading

0 comments on commit 47e0af8

Please sign in to comment.