Browse Source

Force modifyRule command handler to fail if an incompatible old fastjson found (#1377)

* Note that this is only a temporary solution.
master
Jason Joo GitHub 4 years ago
parent
commit
49e60a3e51
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 1 deletions
  1. +65
    -0
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java
  2. +19
    -0
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java
  3. +11
    -1
      sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyRulesCommandHandler.java

+ 65
- 0
sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java View File

@@ -36,4 +36,69 @@ public final class VersionUtil {
}

private VersionUtil() {}
private static int parseInt(String str) {
if (str == null || str.length() < 1) {
return 0;
}
int num = 0;
for (int i = 0; i < str.length(); i ++) {
char ch = str.charAt(i);
if (ch < '0' || ch > '9') {
break;
}
num = num * 10 + (ch - '0');
}
return num;
}

/**
* Convert version in string like x.y.z or x.y.z.b into number<br />
* Each segment has one byte space(unsigned)<br />
* eg.<br />
* <pre>
* 1.2.3.4 => 01 02 03 04
* 1.2.3 => 01 02 03 00
* 1.2 => 01 02 00 00
* 1 => 01 00 00 00
* </pre>
*
* @return
*/
public static int fromVersionString(String verStr) {
if (verStr == null || verStr.length() < 1) {
return 0;
}
int[] versions = new int[] {0, 0, 0, 0};
int index = 0;
String segment;
int cur = 0;
int pos;
do {
if (index >= versions.length) {
// More dots than "x.y.z.b" contains
return 0;
}
pos = verStr.indexOf('.', cur);
if (pos == -1) {
segment = verStr.substring(cur);
} else if (cur < pos) {
segment = verStr.substring(cur, pos);
} else {
// Illegal format
return 0;
}
versions[index] = parseInt(segment);
if (versions[index] < 0 || versions[index] > 255) {
// Out of range [0, 255]
return 0;
}
cur = pos + 1;
index ++;
} while (pos > 0);
return ((versions[0] & 0xff) << 24)
| ((versions[1] & 0xff) << 16)
| ((versions[2] & 0xff) << 8)
| (versions[3] & 0xff);
}
}

+ 19
- 0
sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java View File

@@ -15,6 +15,8 @@
*/
package com.alibaba.csp.sentinel.util;

import static org.junit.Assert.*;

import org.junit.Assert;
import org.junit.Test;

@@ -27,4 +29,21 @@ public class VersionUtilTest {
// Manifest cannot be load before package.
Assert.assertEquals(defaultVersion, version);
}
@Test
public void testFromVersionString() {
assertEquals(0x01020300, VersionUtil.fromVersionString("1.2.3"));
assertEquals(0x01020304, VersionUtil.fromVersionString("1.2.3.4"));
assertEquals(0x0102ff04, VersionUtil.fromVersionString("1.2.255.4"));
assertEquals(0xffffffff, VersionUtil.fromVersionString("255.255.255.255"));
assertEquals(0, VersionUtil.fromVersionString("1.255.256.0"));
assertEquals(0x01020000, VersionUtil.fromVersionString("1.2."));
assertEquals(0x01000000, VersionUtil.fromVersionString("1"));
assertEquals(0x01020000, VersionUtil.fromVersionString("1.2"));
assertEquals(0, VersionUtil.fromVersionString("test"));
assertEquals(0x01020300, VersionUtil.fromVersionString("1.2.3-"));
assertEquals(0x01020300, VersionUtil.fromVersionString("1.2.3b"));
assertEquals(0x01023c00, VersionUtil.fromVersionString("1.2.60.sec9"));
assertEquals(0x01023c00, VersionUtil.fromVersionString("1.2.60-internal"));
}
}

+ 11
- 1
sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyRulesCommandHandler.java View File

@@ -25,6 +25,7 @@ import com.alibaba.csp.sentinel.command.annotation.CommandMapping;
import com.alibaba.csp.sentinel.datasource.WritableDataSource;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.csp.sentinel.util.VersionUtil;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
@@ -33,6 +34,7 @@ import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;

import static com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry.*;
@@ -43,9 +45,17 @@ import static com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry
*/
@CommandMapping(name = "setRules", desc = "modify the rules, accept param: type={ruleType}&data={ruleJson}")
public class ModifyRulesCommandHandler implements CommandHandler<String> {
private static final int FASTJSON_MINIMAL_VER = 0x01020C00;

@Override
public CommandResponse<String> handle(CommandRequest request) {
// XXX from 1.7.2, force to fail when fastjson is older than 1.2.12
// We may need a better solution on this.
if (VersionUtil.fromVersionString(JSON.VERSION) < FASTJSON_MINIMAL_VER) {
// fastjson too old
return CommandResponse.ofFailure(new RuntimeException("The \"fastjson-" + JSON.VERSION
+ "\" introduced in application is too old, you need fastjson-1.2.12 at least."));
}
String type = request.getParam("type");
// rule data in get parameter
String data = request.getParam("data");
@@ -58,7 +68,7 @@ public class ModifyRulesCommandHandler implements CommandHandler<String> {
}
}

RecordLog.info(String.format("Receiving rule change (type: %s): %s", type, data));
RecordLog.info("Receiving rule change (type: {}): {}", type, data);

String result = "success";



Loading…
Cancel
Save