diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 72964d7..b1cab36 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,7 +41,7 @@ jobs: - name: "Test, Check style, Check PMD, Check license with Maven and Java8" if: matrix.java == '8' run: | - ./mvnw -T 4C clean test + ./mvnw -T 4C clean test && sh ./tools/check_format.sh - name: "Test with Maven and Java${{ matrix.java }}" if: matrix.java != '8' run: | diff --git a/pom.xml b/pom.xml index f224096..21976a7 100644 --- a/pom.xml +++ b/pom.xml @@ -9,14 +9,16 @@ 1.0-SNAPSHOT - 8 - 8 + 1.8 + 1.8 UTF-8 ${user.dir} 0.3.1 5.8.2 1.6.0 1.2.9 + 1.3.6 + 3.8 @@ -138,6 +140,45 @@ true + + + org.apache.maven.plugins + maven-pmd-plugin + ${maven-pmd-plugin.version} + + ${project.build.sourceEncoding} + 2 + true + + rulesets/java/ali-comment.xml + rulesets/java/ali-concurrent.xml + rulesets/java/ali-constant.xml + rulesets/java/ali-exception.xml + rulesets/java/ali-flowcontrol.xml + rulesets/java/ali-naming.xml + rulesets/java/ali-oop.xml + rulesets/java/ali-orm.xml + rulesets/java/ali-other.xml + rulesets/java/ali-set.xml + + + + + pmd-check + validate + + check + + + + + + com.alibaba.p3c + p3c-pmd + ${p3c-pmd.version} + + + \ No newline at end of file diff --git a/src/main/java/org/redis2asp/protocol/RedisCommandDecoder.java b/src/main/java/org/redis2asp/protocol/RedisCommandDecoder.java index cbf09ee..222e9f2 100644 --- a/src/main/java/org/redis2asp/protocol/RedisCommandDecoder.java +++ b/src/main/java/org/redis2asp/protocol/RedisCommandDecoder.java @@ -58,8 +58,11 @@ private RedisRequest convert2RedisRequest(List params) { return new GetRequest(params.get(1)); case "command": return new CommandRequest(); + case "setnx": + params.add("nx"); + return new SetRequest(params); case "set": - return new SetRequest(params.get(1), params.get(2), params); + return new SetRequest(params); default: return null; } diff --git a/src/main/java/org/redis2asp/protocol/RedisCommandHandler.java b/src/main/java/org/redis2asp/protocol/RedisCommandHandler.java index 2cc1847..00d5bee 100644 --- a/src/main/java/org/redis2asp/protocol/RedisCommandHandler.java +++ b/src/main/java/org/redis2asp/protocol/RedisCommandHandler.java @@ -132,7 +132,11 @@ public void onFailure(AerospikeException ae) { client.put(null, new WriteListener() { @Override public void onSuccess(Key key) { - setRequest.setResponse("OK".getBytes(StandardCharsets.UTF_8)); + if (setRequest.getOriginalCommand().contains("nx")) { + setRequest.setResponse("1".getBytes(StandardCharsets.UTF_8)); + } else { + setRequest.setResponse("OK".getBytes(StandardCharsets.UTF_8)); + } ctx.writeAndFlush(redisRequest.getResponse()); } diff --git a/src/main/java/org/redis2asp/protocol/RedisResponse.java b/src/main/java/org/redis2asp/protocol/RedisResponse.java index e3f908d..e0929f8 100644 --- a/src/main/java/org/redis2asp/protocol/RedisResponse.java +++ b/src/main/java/org/redis2asp/protocol/RedisResponse.java @@ -34,7 +34,7 @@ public interface RedisResponse extends RemotingCommand { byte[] CRLF = new byte[] {'\r', '\n'}; T data(); - + void setData(byte[] data); void write(ByteBuf out) throws IOException; default ProtocolCode getProtocolCode() { diff --git a/src/main/java/org/redis2asp/protocol/request/SetRequest.java b/src/main/java/org/redis2asp/protocol/request/SetRequest.java index 5b9417a..f4c61ac 100644 --- a/src/main/java/org/redis2asp/protocol/request/SetRequest.java +++ b/src/main/java/org/redis2asp/protocol/request/SetRequest.java @@ -21,24 +21,28 @@ import org.redis2asp.protocol.RedisRequest; import org.redis2asp.protocol.RedisResponse; import org.redis2asp.protocol.response.BulkResponse; +import org.redis2asp.protocol.response.IntegerResponse; public class SetRequest implements RedisRequest { - final String key; + final String originalCommand; - final String value; + final String key; - TtlType ttlType; + final String value; - Long ttl; + TtlType ttlType; - Operate operate; + Long ttl; - BulkResponse response = new BulkResponse(); + Operate operate; - public SetRequest(String key, String value, List params) { - this.key = key; - this.value = value; + RedisResponse response; + + public SetRequest(List params) { + this.originalCommand = params.get(0); + this.key = params.get(1); + this.value = params.get(2); if (params.contains("nx")) { this.operate = Operate.NX; } else if (params.contains("xx")) { @@ -51,6 +55,11 @@ public SetRequest(String key, String value, List params) { this.ttlType = TtlType.PX; this.ttl = Long.parseLong(params.get(params.indexOf("px") + 1)); } + if (originalCommand.contains("nx")) { + this.response = new IntegerResponse(); + } else { + this.response = new BulkResponse(); + } } public String getKey() { @@ -83,17 +92,36 @@ public RedisResponse getResponse() { return response; } + public String getOriginalCommand() { + return originalCommand; + } + public enum TtlType { - EX, PX + /** + * EX seconds -- Set the specified expire time, in seconds. + */ + EX, + /** + * PX milliseconds -- Set the specified expire time, in milliseconds. + */ + PX } public enum Operate { - NX, XX + /** + * NX -- Only set the key if it does not already exist. + */ + NX, + /** + * XX -- Only set the key if it already exist. + */ + XX } @Override public String toString() { - return "SetRequest{" + "key='" + key + '\'' + ", value='" + value + '\'' + ", ttlType=" + ttlType + ", ttl=" - + ttl + ", operate=" + operate + ", response=" + response + '}'; + return "SetRequest{" + "originalCommand='" + originalCommand + '\'' + ", key='" + key + '\'' + ", value='" + + value + '\'' + ", ttlType=" + ttlType + ", ttl=" + ttl + ", operate=" + operate + ", response=" + + response + '}'; } } diff --git a/src/main/java/org/redis2asp/protocol/response/IntegerResponse.java b/src/main/java/org/redis2asp/protocol/response/IntegerResponse.java index 9ff051f..7e2196b 100644 --- a/src/main/java/org/redis2asp/protocol/response/IntegerResponse.java +++ b/src/main/java/org/redis2asp/protocol/response/IntegerResponse.java @@ -17,28 +17,37 @@ package org.redis2asp.protocol.response; import java.io.IOException; +import java.nio.charset.StandardCharsets; import io.netty.buffer.ByteBuf; import org.redis2asp.protocol.RedisResponse; -public class IntegerResponse implements RedisResponse { +public class IntegerResponse implements RedisResponse { private static final char MARKER = ':'; - private final int data; + private byte[] data; public IntegerResponse(int data) { - this.data = data; + this.data = String.valueOf(data).getBytes(StandardCharsets.UTF_8); + } + + public IntegerResponse() { } @Override - public Integer data() { + public byte[] data() { return this.data; } + @Override + public void setData(byte[] data) { + this.data = data; + } + @Override public void write(ByteBuf out) throws IOException { out.writeByte(MARKER); - out.writeBytes(String.valueOf(data).getBytes()); + out.writeBytes(data == null ? "0".getBytes(StandardCharsets.UTF_8) : data); out.writeBytes(CRLF); } diff --git a/src/test/java/org/redis2asp/ServerTest.java b/src/test/java/org/redis2asp/ServerTest.java index b54656c..3770a4f 100644 --- a/src/test/java/org/redis2asp/ServerTest.java +++ b/src/test/java/org/redis2asp/ServerTest.java @@ -104,6 +104,11 @@ public void testSetNxNilAsp() { Assertions.assertEquals(result, "OK"); result = jedis.set(key, "b", SetParams.setParams().nx()); Assertions.assertNull(result); + key = String.valueOf(ThreadLocalRandom.current().nextInt(50000)); + result = String.valueOf(jedis.setnx(key, "b")); + Assertions.assertEquals(result, "1"); + result = String.valueOf(jedis.setnx(key, "b")); + Assertions.assertEquals(result, "0"); } }