From bd41bdf2701a820c19de5a3e3445f57216bb037f Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 09:39:24 +0800 Subject: [PATCH 01/31] optimize: update README.md --- .github/workflows/build.yml | 1 - README.md | 17 +++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index de947e1..0a6272b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,6 @@ on: branches: [ main ] jobs: - # job 1: Test based on java 8 and 21. Do not checkstyle. build: name: "build" services: diff --git a/README.md b/README.md index 8c034eb..30933e7 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,15 @@ High-performance Aerospike proxy for the Redis protocold Details can be found here: [redispike-proxy/src/test/java/icu/funkye/redispike/ServerTest.java at main · funky-eyes/redispike-proxy (github.com)](https://github.com/funky-eyes/redispike-proxy/blob/main/src/test/java/icu/funkye/redispike/ServerTest.java) -| feature | note | -| ------- | -------------------------------------------------------- | -| String | Perfect support | -| Hash | HSETNX only supports the key level, not the column level | -| List | Not support | -| pub/sub | Ready for support | -| Set | Ready for support | -| ZSet | | +| feature | support | note | +|---------|---------|------| +| String | done | | +| Hash | done | HSETNX only supports the key level, not the column level | +| Scan | | | +| List | | | +| Set | | | +| ZSet | | | +| keys | | | From 589a6b2a29f58dbbc48beb7da4f3f432634daff0 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 10:08:37 +0800 Subject: [PATCH 02/31] optimize: update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 30933e7..7514456 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ # redis2asp High-performance Aerospike proxy for the Redis protocold +### compatibility + +Aerospike: 3.x - 7.x (8.x version has not been tested yet as there is no Docker image available currently) +Redis 3.x - 7.x + ### support mode Details can be found here: [redispike-proxy/src/test/java/icu/funkye/redispike/ServerTest.java at main · funky-eyes/redispike-proxy (github.com)](https://github.com/funky-eyes/redispike-proxy/blob/main/src/test/java/icu/funkye/redispike/ServerTest.java) From 53693513cae29bc37ee44b313b7b305be7e60ab5 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 15:48:42 +0800 Subject: [PATCH 03/31] feature: support keys protocol --- .../handler/RedisCommandHandler.java | 3 + .../process/impl/CommandRequestProcessor.java | 2 +- .../process/impl/DelRequestProcessor.java | 3 +- .../process/impl/GetRequestProcessor.java | 2 +- .../process/impl/HDelRequestProcessor.java | 4 +- .../process/impl/HSetRequestProcessor.java | 2 +- .../process/impl/KeysRequestProcessor.java | 94 +++++++++ .../process/impl/SetRequestProcessor.java | 6 +- .../protocol/RedisCommandDecoder.java | 3 + .../redispike/protocol/RedisResponse.java | 3 +- .../protocol/request/CommandRequest.java | 8 +- .../protocol/request/DelRequest.java | 6 +- .../protocol/request/GetRequest.java | 6 +- .../protocol/request/HDelRequest.java | 6 +- .../protocol/request/HSetRequest.java | 10 +- .../protocol/request/KeysRequest.java | 67 +++++++ .../protocol/request/SetRequest.java | 8 +- .../protocol/response/BulkResponse.java | 66 ++++--- .../protocol/response/IntegerResponse.java | 17 +- .../icu/funkye/redispike/util/IdWorker.java | 184 ++++++++++++++++++ .../funkye/redispike/util/UUIDGenerator.java | 49 +++++ .../java/icu/funkye/redispike/ServerTest.java | 25 ++- 22 files changed, 498 insertions(+), 76 deletions(-) create mode 100644 src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java create mode 100644 src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java create mode 100644 src/main/java/icu/funkye/redispike/util/IdWorker.java create mode 100644 src/main/java/icu/funkye/redispike/util/UUIDGenerator.java diff --git a/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java b/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java index 1b828bf..426e06f 100644 --- a/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java +++ b/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java @@ -27,6 +27,7 @@ import icu.funkye.redispike.handler.process.impl.GetRequestProcessor; import icu.funkye.redispike.handler.process.impl.HDelRequestProcessor; import icu.funkye.redispike.handler.process.impl.HSetRequestProcessor; +import icu.funkye.redispike.handler.process.impl.KeysRequestProcessor; import icu.funkye.redispike.handler.process.impl.SetRequestProcessor; import icu.funkye.redispike.handler.process.impl.CommandRequestProcessor; import icu.funkye.redispike.handler.process.impl.DelRequestProcessor; @@ -54,6 +55,8 @@ public RedisCommandHandler() { processorMap.put(hDelRequestProcessor.getCmdCode().value(), hDelRequestProcessor); SetRequestProcessor setRequestProcessor = new SetRequestProcessor(); processorMap.put(setRequestProcessor.getCmdCode().value(), setRequestProcessor); + KeysRequestProcessor keysRequestProcessor = new KeysRequestProcessor(); + processorMap.put(keysRequestProcessor.getCmdCode().value(), keysRequestProcessor); } @Override diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/CommandRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/CommandRequestProcessor.java index e55a198..16f8fa7 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/CommandRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/CommandRequestProcessor.java @@ -31,7 +31,7 @@ public CommandRequestProcessor() { @Override public void handle(RemotingContext ctx, CommandRequest request) { - request.setResponse("OK".getBytes(StandardCharsets.UTF_8)); + request.setResponse("OK"); ctx.writeAndFlush(request.getResponse()); } } diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java index 4efaaaa..e8064d5 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java @@ -48,8 +48,7 @@ public DelRequestProcessor() { client.delete(AeroSpikeClientFactory.eventLoops.next(), new DeleteListener() { @Override public void onSuccess(Key key, boolean b) { - request.setResponse(String.valueOf(request.getCount().incrementAndGet()) - .getBytes(StandardCharsets.UTF_8)); + request.setResponse(String.valueOf(request.getCount().incrementAndGet())); countDownLatch.countDown(); } diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/GetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/GetRequestProcessor.java index d4c1f29..27748df 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/GetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/GetRequestProcessor.java @@ -47,7 +47,7 @@ public void onSuccess(Key key, Record record) { } String value = record.getString(request.getKey()); if (StringUtil.isNotBlank(value)) { - request.setResponse(value.getBytes(StandardCharsets.UTF_8)); + request.setResponse(value); } ctx.writeAndFlush(request.getResponse()); } diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/HDelRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/HDelRequestProcessor.java index a85c51d..4238a9d 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/HDelRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/HDelRequestProcessor.java @@ -54,7 +54,7 @@ public void onSuccess(Key key, Record record) { @Override public void onSuccess(Key key, boolean b) { request.setResponse( - String.valueOf(request.getFields().size()).getBytes(StandardCharsets.UTF_8)); + String.valueOf(request.getFields().size())); ctx.writeAndFlush(request.getResponse()); } @@ -71,7 +71,7 @@ public void onFailure(AerospikeException exception) { @Override public void onSuccess(Key key) { request.setResponse( - String.valueOf(request.getFields().size()).getBytes(StandardCharsets.UTF_8)); + String.valueOf(request.getFields().size())); ctx.writeAndFlush(request.getResponse()); } diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java index aa5094a..ff470c1 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java @@ -53,7 +53,7 @@ public void handle(RemotingContext ctx, HSetRequest request) { client.put(AeroSpikeClientFactory.eventLoops.next(), new WriteListener() { @Override public void onSuccess(Key key) { - request.setResponse(String.valueOf(request.getKv().size()).getBytes(StandardCharsets.UTF_8)); + request.setResponse(String.valueOf(request.getKv().size())); ctx.writeAndFlush(request.getResponse()); } diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java new file mode 100644 index 0000000..bee07ac --- /dev/null +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java @@ -0,0 +1,94 @@ +/* + * 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 icu.funkye.redispike.handler.process.impl; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import com.aerospike.client.AerospikeException; +import com.aerospike.client.Bin; +import com.aerospike.client.Key; +import com.aerospike.client.Record; +import com.aerospike.client.Value; +import com.aerospike.client.listener.RecordListener; +import com.aerospike.client.listener.RecordSequenceListener; +import com.aerospike.client.policy.ScanPolicy; +import com.alipay.remoting.RemotingContext; +import com.alipay.sofa.common.profile.StringUtil; + +import icu.funkye.redispike.factory.AeroSpikeClientFactory; +import icu.funkye.redispike.handler.process.AbstractRedisRequestProcessor; +import icu.funkye.redispike.protocol.RedisRequestCommandCode; +import icu.funkye.redispike.protocol.request.GetRequest; +import icu.funkye.redispike.protocol.request.KeysRequest; +import icu.funkye.redispike.util.IdWorker; +import icu.funkye.redispike.util.IntegerUtils; +import icu.funkye.redispike.util.UUIDGenerator; + +public class KeysRequestProcessor extends AbstractRedisRequestProcessor { + + final long MAX_ID = (long) Math.pow(10, 14); + + public KeysRequestProcessor() { + this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(KeysRequest.class.hashCode())); + } + + @Override + public void handle(RemotingContext ctx, KeysRequest request) { + ScanPolicy scanPolicy = new ScanPolicy(client.getScanPolicyDefault()); + scanPolicy.includeBinData = false; + scanPolicy.failOnClusterChange = true; + client.scanAll(AeroSpikeClientFactory.eventLoops.next(), new RecordSequenceListener() { + @Override + public void onRecord(Key key, Record record) throws AerospikeException { + request.setResponse(key.userKey.toString()); + } + + @Override + public void onSuccess() { + ctx.writeAndFlush(request.getResponse()); + } + + @Override + public void onFailure(AerospikeException exception) { + logger.error(exception.getMessage(), exception); + ctx.writeAndFlush(request.getResponse()); + } + }, scanPolicy, AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set); + } + + /* + public static void main(String[] args) { + List list = new ArrayList<>(); + list.add("keys"); + list.add("*"); + KeysRequest keysRequest = new KeysRequest(list); + Set set = new HashSet<>(); + set.add("1"); + set.add("2"); + keysRequest.setResponse(Arrays.toString(set.toArray(new String[0])).getBytes(StandardCharsets.UTF_8)); + System.out.println(new String(keysRequest.getResponse().data())); + + } + */ + +} diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java index 88f9405..b188656 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java @@ -69,7 +69,7 @@ public void onSuccess(Key key, Record record) { client.put(AeroSpikeClientFactory.eventLoops.next(), new WriteListener() { @Override public void onSuccess(Key key) { - request.setResponse("OK".getBytes(StandardCharsets.UTF_8)); + request.setResponse("OK"); ctx.writeAndFlush(request.getResponse()); } @@ -98,9 +98,9 @@ public void onFailure(AerospikeException ae) { @Override public void onSuccess(Key key) { if (request.getOriginalCommand().contains("nx")) { - request.setResponse("1".getBytes(StandardCharsets.UTF_8)); + request.setResponse("1"); } else { - request.setResponse("OK".getBytes(StandardCharsets.UTF_8)); + request.setResponse("OK"); } ctx.writeAndFlush(request.getResponse()); } diff --git a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java index 2391481..4cc0a65 100644 --- a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java +++ b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java @@ -22,6 +22,7 @@ import com.alipay.remoting.CommandDecoder; import icu.funkye.redispike.protocol.request.HDelRequest; import icu.funkye.redispike.protocol.request.HSetRequest; +import icu.funkye.redispike.protocol.request.KeysRequest; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.DecoderException; @@ -73,6 +74,8 @@ private RedisRequest convert2RedisRequest(List params) { return new SetRequest(params); case "set": return new SetRequest(params); + case "keys": + return new KeysRequest(params); case "del": params.remove(0); return new DelRequest(params); diff --git a/src/main/java/icu/funkye/redispike/protocol/RedisResponse.java b/src/main/java/icu/funkye/redispike/protocol/RedisResponse.java index fd3a72b..986bb66 100644 --- a/src/main/java/icu/funkye/redispike/protocol/RedisResponse.java +++ b/src/main/java/icu/funkye/redispike/protocol/RedisResponse.java @@ -33,8 +33,7 @@ public interface RedisResponse extends RemotingCommand { byte[] CRLF = new byte[] {'\r', '\n'}; - T data(); - void setData(byte[] data); + void setData(T data); void write(ByteBuf out) throws IOException; default ProtocolCode getProtocolCode() { diff --git a/src/main/java/icu/funkye/redispike/protocol/request/CommandRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/CommandRequest.java index dc54fc7..397f493 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/CommandRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/CommandRequest.java @@ -20,17 +20,17 @@ import icu.funkye.redispike.protocol.RedisResponse; import icu.funkye.redispike.protocol.response.BulkResponse; -public class CommandRequest implements RedisRequest { +public class CommandRequest implements RedisRequest { - private BulkResponse response = new BulkResponse(); + private final BulkResponse response = new BulkResponse(); @Override - public RedisResponse getResponse() { + public RedisResponse getResponse() { return response; } @Override - public void setResponse(byte[] data) { + public void setResponse(String data) { response.setData(data); } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/DelRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/DelRequest.java index 2bbade5..1545123 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/DelRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/DelRequest.java @@ -22,7 +22,7 @@ import icu.funkye.redispike.protocol.RedisResponse; import icu.funkye.redispike.protocol.response.IntegerResponse; -public class DelRequest implements RedisRequest { +public class DelRequest implements RedisRequest { List key; @@ -39,7 +39,7 @@ public List getKey() { } @Override - public void setResponse(byte[] data) { + public void setResponse(String data) { this.response.setData(data); } @@ -48,7 +48,7 @@ public AtomicInteger getCount() { } @Override - public RedisResponse getResponse() { + public RedisResponse getResponse() { return response; } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/GetRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/GetRequest.java index 7e82588..387c5a9 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/GetRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/GetRequest.java @@ -20,7 +20,7 @@ import icu.funkye.redispike.protocol.RedisResponse; import icu.funkye.redispike.protocol.response.BulkResponse; -public class GetRequest implements RedisRequest { +public class GetRequest implements RedisRequest { String key; @@ -35,12 +35,12 @@ public String getKey() { } @Override - public void setResponse(byte[] data) { + public void setResponse(String data) { this.response.setData(data); } @Override - public RedisResponse getResponse() { + public RedisResponse getResponse() { return response; } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/HDelRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/HDelRequest.java index 8d940ff..53d186b 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/HDelRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/HDelRequest.java @@ -25,7 +25,7 @@ import icu.funkye.redispike.protocol.RedisResponse; import icu.funkye.redispike.protocol.response.IntegerResponse; -public class HDelRequest implements RedisRequest { +public class HDelRequest implements RedisRequest { String key; @@ -40,12 +40,12 @@ public HDelRequest(List params) { } @Override - public void setResponse(byte[] data) { + public void setResponse(String data) { this.response.setData(data); } @Override - public RedisResponse getResponse() { + public RedisResponse getResponse() { return response; } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/HSetRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/HSetRequest.java index 62372e4..42fdb2e 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/HSetRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/HSetRequest.java @@ -25,7 +25,7 @@ import icu.funkye.redispike.protocol.response.IntegerResponse; import icu.funkye.redispike.util.CollectionUtils; -public class HSetRequest implements RedisRequest { +public class HSetRequest implements RedisRequest { final String originalCommand; @@ -35,7 +35,7 @@ public class HSetRequest implements RedisRequest { Operate operate; - RedisResponse response; + RedisResponse response; public HSetRequest(List params) { this.originalCommand = params.remove(0); @@ -50,12 +50,12 @@ public HSetRequest(List params) { } @Override - public RedisResponse getResponse() { + public RedisResponse getResponse() { return this.response; } @Override - public void setResponse(byte[] data) { + public void setResponse(String data) { this.response.setData(data); } @@ -75,7 +75,7 @@ public void setOperate(Operate operate) { this.operate = operate; } - public void setResponse(RedisResponse response) { + public void setResponse(RedisResponse response) { this.response = response; } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java new file mode 100644 index 0000000..d32334e --- /dev/null +++ b/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java @@ -0,0 +1,67 @@ +/* + * 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 icu.funkye.redispike.protocol.request; + +import java.util.ArrayList; +import java.util.List; + +import icu.funkye.redispike.protocol.RedisRequest; +import icu.funkye.redispike.protocol.RedisResponse; +import icu.funkye.redispike.protocol.request.conts.Operate; +import icu.funkye.redispike.protocol.request.conts.TtlType; +import icu.funkye.redispike.protocol.response.BulkResponse; +import icu.funkye.redispike.protocol.response.IntegerResponse; + +public class KeysRequest implements RedisRequest { + + final String originalCommand; + + final String pattern; + + BulkResponse response; + + public KeysRequest(List params) { + this.originalCommand = params.get(0); + this.pattern = params.get(1); + this.response = new BulkResponse(new ArrayList<>()); + } + + @Override + public void setResponse(String data) { + this.response.appender(data); + } + + @Override + public RedisResponse getResponse() { + return response; + } + + public String getOriginalCommand() { + return originalCommand; + } + + public String getPattern() { + return pattern; + } + + @Override + public String toString() { + return "KeysRequest{" + "originalCommand='" + originalCommand + '\'' + ", pattern='" + pattern + '\'' + + ", response=" + response + '}'; + } + +} diff --git a/src/main/java/icu/funkye/redispike/protocol/request/SetRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/SetRequest.java index e5846a3..1f9cd8d 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/SetRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/SetRequest.java @@ -25,7 +25,7 @@ import icu.funkye.redispike.protocol.response.BulkResponse; import icu.funkye.redispike.protocol.response.IntegerResponse; -public class SetRequest implements RedisRequest { +public class SetRequest implements RedisRequest { final String originalCommand; @@ -39,7 +39,7 @@ public class SetRequest implements RedisRequest { Operate operate; - RedisResponse response; + RedisResponse response; public SetRequest(List params) { this.originalCommand = params.get(0); @@ -85,12 +85,12 @@ public Operate getOperate() { } @Override - public void setResponse(byte[] data) { + public void setResponse(String data) { this.response.setData(data); } @Override - public RedisResponse getResponse() { + public RedisResponse getResponse() { return response; } diff --git a/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java b/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java index d367eea..3bbe066 100644 --- a/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java +++ b/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java @@ -17,62 +17,74 @@ package icu.funkye.redispike.protocol.response; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import io.netty.buffer.ByteBuf; import icu.funkye.redispike.protocol.RedisResponse; -public class BulkResponse implements RedisResponse { +public class BulkResponse implements RedisResponse { - public static final BulkResponse NIL_REPLY = new BulkResponse(); + private static final char MARKER = '$'; - private static final char MARKER = '$'; + private static final char PREFIX = '+'; - private static final char PREFIX = '+'; + private static final char ERROR_PREFIX = '-'; - private byte[] data; + private static final char ARRAY_PREFIX = '*'; - private int len; + private List list; - public BulkResponse() { - this.data = null; - this.len = -1; + private String data; + + public BulkResponse(List list) { + this.list = list; } - public BulkResponse(byte[] data) { + public BulkResponse(String data) { this.data = data; - this.len = data.length; } - @Override - public byte[] data() { - return this.data; + public BulkResponse() { } - public byte[] getData() { - return data; + public void appender(String data) { + list.add(data.getBytes(StandardCharsets.UTF_8)); } - public void setData(byte[] data) { + public void setData(String data) { this.data = data; - this.len = data.length; } @Override public void write(ByteBuf out) throws IOException { - // 1.Write header - out.writeByte(MARKER); - out.writeBytes(String.valueOf(len).getBytes()); - out.writeBytes(CRLF); - - // 2.Write data - if (len > 0) { - out.writeBytes(data); + if (list != null && list.size() > 0) { + out.writeByte(ARRAY_PREFIX); + out.writeBytes(String.valueOf(list.size()).getBytes(StandardCharsets.UTF_8)); + out.writeBytes(CRLF); + for (byte[] data : list) { + out.writeByte(MARKER); + out.writeBytes(String.valueOf(data.length).getBytes(StandardCharsets.UTF_8)); + out.writeBytes(CRLF); + out.writeBytes(data); + out.writeBytes(CRLF); + } + return; + } + if (data == null) { + out.writeByte(MARKER); + out.writeBytes(String.valueOf(-1).getBytes()); + out.writeBytes(CRLF); + } else { + out.writeByte(PREFIX); + out.writeBytes(data.getBytes(StandardCharsets.UTF_8)); out.writeBytes(CRLF); } } @Override public String toString() { - return "BulkReply{" + "bytes=" + Arrays.toString(data) + '}'; + return "BulkResponse{" + "list=" + list + '}'; } } diff --git a/src/main/java/icu/funkye/redispike/protocol/response/IntegerResponse.java b/src/main/java/icu/funkye/redispike/protocol/response/IntegerResponse.java index 75615e0..b5ecc17 100644 --- a/src/main/java/icu/funkye/redispike/protocol/response/IntegerResponse.java +++ b/src/main/java/icu/funkye/redispike/protocol/response/IntegerResponse.java @@ -21,33 +21,28 @@ import io.netty.buffer.ByteBuf; import icu.funkye.redispike.protocol.RedisResponse; -public class IntegerResponse implements RedisResponse { +public class IntegerResponse implements RedisResponse { private static final char MARKER = ':'; - private byte[] data; + private String data; - public IntegerResponse(int data) { - this.data = String.valueOf(data).getBytes(StandardCharsets.UTF_8); + public IntegerResponse(String data) { + this.data = data; } public IntegerResponse() { } @Override - public byte[] data() { - return this.data; - } - - @Override - public void setData(byte[] data) { + public void setData(String data) { this.data = data; } @Override public void write(ByteBuf out) throws IOException { out.writeByte(MARKER); - out.writeBytes(data == null ? "0".getBytes(StandardCharsets.UTF_8) : data); + out.writeBytes(data == null ? "0".getBytes(StandardCharsets.UTF_8) : data.getBytes(StandardCharsets.UTF_8)); out.writeBytes(CRLF); } diff --git a/src/main/java/icu/funkye/redispike/util/IdWorker.java b/src/main/java/icu/funkye/redispike/util/IdWorker.java new file mode 100644 index 0000000..0b3989c --- /dev/null +++ b/src/main/java/icu/funkye/redispike/util/IdWorker.java @@ -0,0 +1,184 @@ +/* + * 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 icu.funkye.redispike.util; + +import java.net.NetworkInterface; +import java.util.Enumeration; +import java.util.Random; +import java.util.concurrent.atomic.AtomicLong; + +public class IdWorker { + + /** + * Start time cut (2024-04-08 15:20:25) + */ + private final long twepoch = 1712560825670L; + + /** + * The number of bits occupied by workerId + */ + private final int workerIdBits = 10; + + /** + * The number of bits occupied by timestamp + */ + private final int timestampBits = 41; + + /** + * The number of bits occupied by sequence + */ + private final int sequenceBits = 12; + + /** + * Maximum supported machine id, the result is 1023 + */ + private final int maxWorkerId = ~(-1 << workerIdBits); + + /** + * business meaning: machine ID (0 ~ 1023) + * actual layout in memory: + * highest 1 bit: 0 + * middle 10 bit: workerId + * lowest 53 bit: all 0 + */ + private long workerId; + + /** + * timestamp and sequence mix in one Long + * highest 11 bit: not used + * middle 41 bit: timestamp + * lowest 12 bit: sequence + */ + private AtomicLong timestampAndSequence; + + /** + * mask that help to extract timestamp and sequence from a long + */ + private final long timestampAndSequenceMask = ~(-1L << (timestampBits + sequenceBits)); + + /** + * instantiate an IdWorker using given workerId + * @param workerId if null, then will auto assign one + */ + public IdWorker(Long workerId) { + initTimestampAndSequence(); + initWorkerId(workerId); + } + + /** + * init first timestamp and sequence immediately + */ + private void initTimestampAndSequence() { + long timestamp = getNewestTimestamp(); + long timestampWithSequence = timestamp << sequenceBits; + this.timestampAndSequence = new AtomicLong(timestampWithSequence); + } + + /** + * init workerId + * @param workerId if null, then auto generate one + */ + private void initWorkerId(Long workerId) { + if (workerId == null) { + workerId = generateWorkerId(); + } + if (workerId > maxWorkerId || workerId < 0) { + String message = String.format("worker Id can't be greater than %d or less than 0", maxWorkerId); + throw new IllegalArgumentException(message); + } + this.workerId = workerId << (timestampBits + sequenceBits); + } + + /** + * get next UUID(base on snowflake algorithm), which look like: + * highest 1 bit: always 0 + * next 10 bit: workerId + * next 41 bit: timestamp + * lowest 12 bit: sequence + * @return UUID + */ + public long nextId() { + waitIfNecessary(); + long next = timestampAndSequence.incrementAndGet(); + long timestampWithSequence = next & timestampAndSequenceMask; + return workerId | timestampWithSequence; + } + + /** + * block current thread if the QPS of acquiring UUID is too high + * that current sequence space is exhausted + */ + private void waitIfNecessary() { + long currentWithSequence = timestampAndSequence.get(); + long current = currentWithSequence >>> sequenceBits; + long newest = getNewestTimestamp(); + if (current >= newest) { + try { + Thread.sleep(5); + } catch (InterruptedException ignore) { + // don't care + } + } + } + + /** + * get newest timestamp relative to twepoch + */ + private long getNewestTimestamp() { + return System.currentTimeMillis() - twepoch; + } + + /** + * auto generate workerId, try using mac first, if failed, then randomly generate one + * @return workerId + */ + private long generateWorkerId() { + try { + return generateWorkerIdBaseOnMac(); + } catch (Exception e) { + return generateRandomWorkerId(); + } + } + + /** + * use lowest 10 bit of available MAC as workerId + * @return workerId + * @throws Exception when there is no available mac found + */ + private long generateWorkerIdBaseOnMac() throws Exception { + Enumeration all = NetworkInterface.getNetworkInterfaces(); + while (all.hasMoreElements()) { + NetworkInterface networkInterface = all.nextElement(); + boolean isLoopback = networkInterface.isLoopback(); + boolean isVirtual = networkInterface.isVirtual(); + if (isLoopback || isVirtual) { + continue; + } + byte[] mac = networkInterface.getHardwareAddress(); + return ((mac[4] & 0B11) << 8) | (mac[5] & 0xFF); + } + throw new RuntimeException("no available mac found"); + } + + /** + * randomly generate one as workerId + * @return workerId + */ + private long generateRandomWorkerId() { + return new Random().nextInt(maxWorkerId + 1); + } +} diff --git a/src/main/java/icu/funkye/redispike/util/UUIDGenerator.java b/src/main/java/icu/funkye/redispike/util/UUIDGenerator.java new file mode 100644 index 0000000..bd36ff0 --- /dev/null +++ b/src/main/java/icu/funkye/redispike/util/UUIDGenerator.java @@ -0,0 +1,49 @@ +/* + * 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 icu.funkye.redispike.util; + +/** + * The type Uuid generator. + */ +public class UUIDGenerator { + + private static volatile IdWorker idWorker; + + /** + * generate UUID using snowflake algorithm + * @return UUID + */ + public static long generateUUID() { + if (idWorker == null) { + synchronized (UUIDGenerator.class) { + if (idWorker == null) { + init(null); + } + } + } + return idWorker.nextId(); + } + + /** + * init IdWorker + * @param serverNode the server node id, consider as machine id in snowflake + */ + public static void init(Long serverNode) { + idWorker = new IdWorker(serverNode); + } + +} diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index 6c0ed0d..adcd973 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.concurrent.ThreadLocalRandom; import com.aerospike.client.IAerospikeClient; import com.aerospike.client.Key; @@ -35,6 +36,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; import redis.clients.jedis.params.SetParams; public class ServerTest { @@ -53,6 +55,21 @@ public static void init() throws ParseException { aspClient = AeroSpikeClientFactory.getClient(); } + /* @Test + public void testhKeys() { + List keys = new ArrayList<>(); + for (int i = 0; i < 2; i++) { + keys.add(String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue))); + } + try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { + for (String key : keys) { + jedis.set(key, "b"); + } + Set result = jedis.keys("*"); + Assertions.assertEquals(result.size(), keys.size()); + } + }*/ + @Test public void testhHash() { String key = String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue)); @@ -81,7 +98,7 @@ public void testhHash() { @Test public void testRedisSet() { - try (Jedis jedis = new Jedis("127.0.0.1", 6379)) { + try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { String result = jedis.set("a", "bq"); try (Jedis jedis2 = JedisPooledFactory.getJedisInstance()) { String result2 = jedis2.set("a", "bq"); @@ -100,7 +117,7 @@ public void testGetSetAsp() { Record record = aspClient.get(aspClient.getReadPolicyDefault(), key); Map map = record.bins; Assertions.assertEquals(map.get("a"), "b"); - try (Jedis jedis = new Jedis("127.0.0.1", 6789, 3000)) { + try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { String result = jedis.get("a"); Assertions.assertEquals(result, "b"); } @@ -108,8 +125,8 @@ public void testGetSetAsp() { @Test public void testGetNilAsp() { - try (Jedis jedis = new Jedis("127.0.0.1", 6789, 3000)) { - String result = jedis.get(String.valueOf(ThreadLocalRandom.current().nextInt(111))); + try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { + String result = jedis.get(String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue))); Assertions.assertNull(result); } } From f7d6506af22fecf0f3f27b2fe58a99a49406ba33 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 17:24:42 +0800 Subject: [PATCH 04/31] feature: support keys protocol --- pom.xml | 6 +- .../process/impl/KeysRequestProcessor.java | 57 ++++++++++++------- .../process/impl/SetRequestProcessor.java | 10 +--- .../protocol/request/KeysRequest.java | 5 +- .../protocol/response/BulkResponse.java | 2 +- .../java/icu/funkye/redispike/ServerTest.java | 37 +++++++----- 6 files changed, 70 insertions(+), 47 deletions(-) diff --git a/pom.xml b/pom.xml index 0a9fe65..66d137c 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 1.2.9 1.3.6 3.8 - 4.1.2 + 1.0.3-SNAPSHOT @@ -39,8 +39,8 @@ ${log.version} - com.aerospike - aerospike-client + com.tdkv + tdkv-client ${asp-client.version} diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java index bee07ac..b2bf267 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java @@ -21,8 +21,11 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.aerospike.client.AerospikeException; import com.aerospike.client.Bin; @@ -33,6 +36,7 @@ import com.aerospike.client.listener.RecordSequenceListener; import com.aerospike.client.policy.ScanPolicy; import com.alipay.remoting.RemotingContext; +import com.alipay.remoting.util.StringUtils; import com.alipay.sofa.common.profile.StringUtil; import icu.funkye.redispike.factory.AeroSpikeClientFactory; @@ -46,8 +50,6 @@ public class KeysRequestProcessor extends AbstractRedisRequestProcessor { - final long MAX_ID = (long) Math.pow(10, 14); - public KeysRequestProcessor() { this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(KeysRequest.class.hashCode())); } @@ -55,12 +57,44 @@ public KeysRequestProcessor() { @Override public void handle(RemotingContext ctx, KeysRequest request) { ScanPolicy scanPolicy = new ScanPolicy(client.getScanPolicyDefault()); - scanPolicy.includeBinData = false; scanPolicy.failOnClusterChange = true; + scanPolicy.includeBinData = false; + boolean all = StringUtils.equals(request.getPattern(), "*"); + boolean left = request.getPattern().startsWith("*"); + if (left) { + request.setPattern(request.getPattern().substring(1)); + } + boolean right = request.getPattern().endsWith("*"); + if (right) { + request.setPattern(request.getPattern().substring(0, request.getPattern().length() - 1)); + } client.scanAll(AeroSpikeClientFactory.eventLoops.next(), new RecordSequenceListener() { @Override public void onRecord(Key key, Record record) throws AerospikeException { - request.setResponse(key.userKey.toString()); + if (key != null) { + if (key.userKey != null) { + String userKey = key.userKey.toString(); + if (all) { + request.setResponse(userKey); + } else if (left) { + if (right) { + if (userKey.contains(request.getPattern())) { + request.setResponse(userKey); + } + } else if (userKey.endsWith(request.getPattern())) { + request.setResponse(userKey); + } + } else if (right) { + if (userKey.startsWith(request.getPattern())) { + request.setResponse(userKey); + } + } else { + if (StringUtils.equals(userKey, request.getPattern())) { + request.setResponse(userKey); + } + } + } + } } @Override @@ -76,19 +110,4 @@ public void onFailure(AerospikeException exception) { }, scanPolicy, AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set); } - /* - public static void main(String[] args) { - List list = new ArrayList<>(); - list.add("keys"); - list.add("*"); - KeysRequest keysRequest = new KeysRequest(list); - Set set = new HashSet<>(); - set.add("1"); - set.add("2"); - keysRequest.setResponse(Arrays.toString(set.toArray(new String[0])).getBytes(StandardCharsets.UTF_8)); - System.out.println(new String(keysRequest.getResponse().data())); - - } - */ - } diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java index b188656..a53dfbe 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java @@ -44,9 +44,9 @@ public SetRequestProcessor() { public void handle(RemotingContext ctx, SetRequest request) { Bin bin = new Bin(request.getKey(), request.getValue()); Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); - WritePolicy writePolicy = null; + WritePolicy writePolicy = new WritePolicy(client.getWritePolicyDefault()); + writePolicy.sendKey = true; if (request.getTtl() != null) { - writePolicy = new WritePolicy(client.getWritePolicyDefault()); if (request.getTtlType() == TtlType.EX) { writePolicy.expiration = request.getTtl().intValue(); } else { @@ -54,9 +54,6 @@ public void handle(RemotingContext ctx, SetRequest request) { } } if (request.getOperate() != null) { - if (writePolicy == null) { - writePolicy = new WritePolicy(client.getWritePolicyDefault()); - } if (request.getOperate() == Operate.NX) { writePolicy.recordExistsAction = RecordExistsAction.CREATE_ONLY; } else if (request.getOperate() == Operate.XX) { @@ -91,9 +88,6 @@ public void onFailure(AerospikeException ae) { return; } } - if (writePolicy == null) { - writePolicy = client.getWritePolicyDefault(); - } client.put(AeroSpikeClientFactory.eventLoops.next(), new WriteListener() { @Override public void onSuccess(Key key) { diff --git a/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java index d32334e..59f5dad 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java @@ -30,7 +30,7 @@ public class KeysRequest implements RedisRequest { final String originalCommand; - final String pattern; + String pattern; BulkResponse response; @@ -64,4 +64,7 @@ public String toString() { + ", response=" + response + '}'; } + public void setPattern(String pattern) { + this.pattern = pattern; + } } diff --git a/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java b/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java index 3bbe066..46dfc12 100644 --- a/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java +++ b/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java @@ -59,7 +59,7 @@ public void setData(String data) { @Override public void write(ByteBuf out) throws IOException { - if (list != null && list.size() > 0) { + if (list != null) { out.writeByte(ARRAY_PREFIX); out.writeBytes(String.valueOf(list.size()).getBytes(StandardCharsets.UTF_8)); out.writeBytes(CRLF); diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index adcd973..f7bc544 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -36,7 +36,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; -import redis.clients.jedis.Pipeline; import redis.clients.jedis.params.SetParams; public class ServerTest { @@ -45,7 +44,7 @@ public class ServerTest { static Logger logger = LoggerFactory.getLogger(ServerTest.class); - private final int RandomValue = Integer.MAX_VALUE; + private final int RandomValue = 10000000; @BeforeAll public static void init() throws ParseException { @@ -55,20 +54,28 @@ public static void init() throws ParseException { aspClient = AeroSpikeClientFactory.getClient(); } - /* @Test - public void testhKeys() { - List keys = new ArrayList<>(); - for (int i = 0; i < 2; i++) { - keys.add(String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue))); - } - try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { - for (String key : keys) { - jedis.set(key, "b"); - } - Set result = jedis.keys("*"); - Assertions.assertEquals(result.size(), keys.size()); + @Test + public void testhKeys() { + List keys = new ArrayList<>(); + for (int i = 0; i < 2; i++) { + keys.add(String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue))); + } + try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { + for (String key : keys) { + jedis.set(key, "b"); } - }*/ + Set result = jedis.keys("123"); + Assertions.assertEquals(result.size(), 0); + result = jedis.keys("*"); + Assertions.assertNotEquals(result.size(), 0); + result = jedis.keys("*"); + jedis.set("abc123", "123"); + result = jedis.keys("abc*"); + Assertions.assertEquals(result.size(), 1); + result = jedis.keys("*123"); + Assertions.assertEquals(result.size(), 1); + } + } @Test public void testhHash() { From 96d3450fa6b5cd8f718e06d489cd2cbb307c2523 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 17:27:05 +0800 Subject: [PATCH 05/31] feature: support keys protocol --- .../handler/process/AbstractRedisRequestProcessor.java | 8 +++++++- .../handler/process/impl/DelRequestProcessor.java | 7 ++++--- .../handler/process/impl/KeysRequestProcessor.java | 7 ++++--- .../handler/process/impl/SetRequestProcessor.java | 6 ++++-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/java/icu/funkye/redispike/handler/process/AbstractRedisRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/AbstractRedisRequestProcessor.java index 8a69758..cbdd615 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/AbstractRedisRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/AbstractRedisRequestProcessor.java @@ -37,7 +37,13 @@ public abstract class AbstractRedisRequestProcessor> i @Override public void process(RemotingContext ctx, RemotingCommand msg, ExecutorService defaultExecutor) throws Exception { if (defaultExecutor != null) { - defaultExecutor.submit(() -> this.handle(ctx, (T)msg)); + defaultExecutor.submit(() -> { + try { + this.handle(ctx, (T)msg); + } catch (Exception e) { + logger.error("process error: {}",e.getMessage(), e); + } + }); } else { this.handle(ctx, (T)msg); } diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java index e8064d5..0cb4918 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java @@ -38,11 +38,12 @@ public DelRequestProcessor() { this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(DelRequest.class.hashCode())); } - @Override public void handle(RemotingContext ctx, DelRequest request) { + @Override + public void handle(RemotingContext ctx, DelRequest request) { List keys = request.getKey(); List list = - keys.stream().map(key -> new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, key)) - .collect(Collectors.toList()); + keys.stream().map(key -> new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, key)) + .collect(Collectors.toList()); CountDownLatch countDownLatch = new CountDownLatch(list.size()); for (Key key : list) { client.delete(AeroSpikeClientFactory.eventLoops.next(), new DeleteListener() { diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java index b2bf267..e10692f 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java @@ -49,16 +49,17 @@ import icu.funkye.redispike.util.UUIDGenerator; public class KeysRequestProcessor extends AbstractRedisRequestProcessor { + ScanPolicy scanPolicy = new ScanPolicy(client.getScanPolicyDefault()); public KeysRequestProcessor() { this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(KeysRequest.class.hashCode())); + this.scanPolicy.failOnClusterChange = true; + this.scanPolicy.includeBinData = false; } @Override public void handle(RemotingContext ctx, KeysRequest request) { - ScanPolicy scanPolicy = new ScanPolicy(client.getScanPolicyDefault()); - scanPolicy.failOnClusterChange = true; - scanPolicy.includeBinData = false; + boolean all = StringUtils.equals(request.getPattern(), "*"); boolean left = request.getPattern().startsWith("*"); if (left) { diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java index a53dfbe..d09853d 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java @@ -35,17 +35,19 @@ import icu.funkye.redispike.util.IntegerUtils; public class SetRequestProcessor extends AbstractRedisRequestProcessor { + WritePolicy writePolicy; public SetRequestProcessor() { this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(SetRequest.class.hashCode())); + this.writePolicy = new WritePolicy(client.getWritePolicyDefault()); + this.writePolicy.sendKey = true; } @Override public void handle(RemotingContext ctx, SetRequest request) { Bin bin = new Bin(request.getKey(), request.getValue()); Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); - WritePolicy writePolicy = new WritePolicy(client.getWritePolicyDefault()); - writePolicy.sendKey = true; + if (request.getTtl() != null) { if (request.getTtlType() == TtlType.EX) { writePolicy.expiration = request.getTtl().intValue(); From 03ffe17616da1b31404f1f4aeb5818a30670daa8 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 17:29:10 +0800 Subject: [PATCH 06/31] feature: support keys protocol --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7514456..d25749b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Details can be found here: [redispike-proxy/src/test/java/icu/funkye/redispike/S | List | | | | Set | | | | ZSet | | | -| keys | | | +| keys | done | | From 3624af88e36d8181962a7fd42625198661c9dc02 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 17:32:13 +0800 Subject: [PATCH 07/31] feature: support keys protocol --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 66d137c..0a9fe65 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 1.2.9 1.3.6 3.8 - 1.0.3-SNAPSHOT + 4.1.2 @@ -39,8 +39,8 @@ ${log.version} - com.tdkv - tdkv-client + com.aerospike + aerospike-client ${asp-client.version} From 480a6a5f24a75dd2b340c5b86ea475fb34dd9fa0 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 17:54:20 +0800 Subject: [PATCH 08/31] feature: support keys protocol --- .../redispike/handler/process/impl/SetRequestProcessor.java | 3 ++- src/test/java/icu/funkye/redispike/ServerTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java index d09853d..f0fe607 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java @@ -47,7 +47,7 @@ public SetRequestProcessor() { public void handle(RemotingContext ctx, SetRequest request) { Bin bin = new Bin(request.getKey(), request.getValue()); Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); - + WritePolicy writePolicy = this.writePolicy; if (request.getTtl() != null) { if (request.getTtlType() == TtlType.EX) { writePolicy.expiration = request.getTtl().intValue(); @@ -57,6 +57,7 @@ public void handle(RemotingContext ctx, SetRequest request) { } if (request.getOperate() != null) { if (request.getOperate() == Operate.NX) { + writePolicy = new WritePolicy(writePolicy); writePolicy.recordExistsAction = RecordExistsAction.CREATE_ONLY; } else if (request.getOperate() == Operate.XX) { client.get(AeroSpikeClientFactory.eventLoops.next(), new RecordListener() { diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index f7bc544..2f93efa 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -107,7 +107,7 @@ public void testhHash() { public void testRedisSet() { try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { String result = jedis.set("a", "bq"); - try (Jedis jedis2 = JedisPooledFactory.getJedisInstance()) { + try (Jedis jedis2 = new Jedis("127.0.0.1", 6379)) { String result2 = jedis2.set("a", "bq"); Assertions.assertEquals(result, result2); } From aafa4d2a3a4ff40cd70d2ee5a787e4ff3fe067ce Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:00:09 +0800 Subject: [PATCH 09/31] test --- .../redispike/handler/process/impl/KeysRequestProcessor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java index e10692f..acc7e11 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java @@ -75,6 +75,7 @@ public void onRecord(Key key, Record record) throws AerospikeException { if (key != null) { if (key.userKey != null) { String userKey = key.userKey.toString(); + logger.info("userKey:{}", userKey); if (all) { request.setResponse(userKey); } else if (left) { From 69c9d6389aaa6874ea6d6477a5f6c6d101a05ab7 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:03:09 +0800 Subject: [PATCH 10/31] test --- .../redispike/handler/process/impl/SetRequestProcessor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java index f0fe607..8727bd7 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java @@ -49,6 +49,7 @@ public void handle(RemotingContext ctx, SetRequest request) { Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); WritePolicy writePolicy = this.writePolicy; if (request.getTtl() != null) { + writePolicy = new WritePolicy(writePolicy); if (request.getTtlType() == TtlType.EX) { writePolicy.expiration = request.getTtl().intValue(); } else { From 51dbda6027e47a26e8e501fd8e2c4a68ff141d6a Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:05:35 +0800 Subject: [PATCH 11/31] test --- .../handler/process/impl/KeysRequestProcessor.java | 1 + .../handler/process/impl/SetRequestProcessor.java | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java index acc7e11..d5b046a 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java @@ -73,6 +73,7 @@ public void handle(RemotingContext ctx, KeysRequest request) { @Override public void onRecord(Key key, Record record) throws AerospikeException { if (key != null) { + logger.info("userKey:{}", key); if (key.userKey != null) { String userKey = key.userKey.toString(); logger.info("userKey:{}", userKey); diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java index 8727bd7..0235c25 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java @@ -35,19 +35,19 @@ import icu.funkye.redispike.util.IntegerUtils; public class SetRequestProcessor extends AbstractRedisRequestProcessor { - WritePolicy writePolicy; + WritePolicy defaultWritePolicy; public SetRequestProcessor() { this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(SetRequest.class.hashCode())); - this.writePolicy = new WritePolicy(client.getWritePolicyDefault()); - this.writePolicy.sendKey = true; + this.defaultWritePolicy = new WritePolicy(client.getWritePolicyDefault()); + this.defaultWritePolicy.sendKey = true; } @Override public void handle(RemotingContext ctx, SetRequest request) { Bin bin = new Bin(request.getKey(), request.getValue()); Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); - WritePolicy writePolicy = this.writePolicy; + WritePolicy writePolicy = this.defaultWritePolicy; if (request.getTtl() != null) { writePolicy = new WritePolicy(writePolicy); if (request.getTtlType() == TtlType.EX) { From 1b03431547b38abb30f1ea5bc9b68870e4f978af Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:10:31 +0800 Subject: [PATCH 12/31] test --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0a9fe65..6687ae2 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 1.2.9 1.3.6 3.8 - 4.1.2 + 7.2.1 From 6d111db595af10565d0277900e4faa17431edd98 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:11:03 +0800 Subject: [PATCH 13/31] test --- .../redispike/handler/process/impl/KeysRequestProcessor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java index d5b046a..bab2054 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java @@ -53,7 +53,6 @@ public class KeysRequestProcessor extends AbstractRedisRequestProcessor Date: Mon, 8 Apr 2024 18:14:39 +0800 Subject: [PATCH 14/31] test --- pom.xml | 2 +- .../icu/funkye/redispike/util/IdWorker.java | 184 ------------------ .../funkye/redispike/util/UUIDGenerator.java | 49 ----- 3 files changed, 1 insertion(+), 234 deletions(-) delete mode 100644 src/main/java/icu/funkye/redispike/util/IdWorker.java delete mode 100644 src/main/java/icu/funkye/redispike/util/UUIDGenerator.java diff --git a/pom.xml b/pom.xml index 6687ae2..0f23f7a 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 1.2.9 1.3.6 3.8 - 7.2.1 + 4.6.0 diff --git a/src/main/java/icu/funkye/redispike/util/IdWorker.java b/src/main/java/icu/funkye/redispike/util/IdWorker.java deleted file mode 100644 index 0b3989c..0000000 --- a/src/main/java/icu/funkye/redispike/util/IdWorker.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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 icu.funkye.redispike.util; - -import java.net.NetworkInterface; -import java.util.Enumeration; -import java.util.Random; -import java.util.concurrent.atomic.AtomicLong; - -public class IdWorker { - - /** - * Start time cut (2024-04-08 15:20:25) - */ - private final long twepoch = 1712560825670L; - - /** - * The number of bits occupied by workerId - */ - private final int workerIdBits = 10; - - /** - * The number of bits occupied by timestamp - */ - private final int timestampBits = 41; - - /** - * The number of bits occupied by sequence - */ - private final int sequenceBits = 12; - - /** - * Maximum supported machine id, the result is 1023 - */ - private final int maxWorkerId = ~(-1 << workerIdBits); - - /** - * business meaning: machine ID (0 ~ 1023) - * actual layout in memory: - * highest 1 bit: 0 - * middle 10 bit: workerId - * lowest 53 bit: all 0 - */ - private long workerId; - - /** - * timestamp and sequence mix in one Long - * highest 11 bit: not used - * middle 41 bit: timestamp - * lowest 12 bit: sequence - */ - private AtomicLong timestampAndSequence; - - /** - * mask that help to extract timestamp and sequence from a long - */ - private final long timestampAndSequenceMask = ~(-1L << (timestampBits + sequenceBits)); - - /** - * instantiate an IdWorker using given workerId - * @param workerId if null, then will auto assign one - */ - public IdWorker(Long workerId) { - initTimestampAndSequence(); - initWorkerId(workerId); - } - - /** - * init first timestamp and sequence immediately - */ - private void initTimestampAndSequence() { - long timestamp = getNewestTimestamp(); - long timestampWithSequence = timestamp << sequenceBits; - this.timestampAndSequence = new AtomicLong(timestampWithSequence); - } - - /** - * init workerId - * @param workerId if null, then auto generate one - */ - private void initWorkerId(Long workerId) { - if (workerId == null) { - workerId = generateWorkerId(); - } - if (workerId > maxWorkerId || workerId < 0) { - String message = String.format("worker Id can't be greater than %d or less than 0", maxWorkerId); - throw new IllegalArgumentException(message); - } - this.workerId = workerId << (timestampBits + sequenceBits); - } - - /** - * get next UUID(base on snowflake algorithm), which look like: - * highest 1 bit: always 0 - * next 10 bit: workerId - * next 41 bit: timestamp - * lowest 12 bit: sequence - * @return UUID - */ - public long nextId() { - waitIfNecessary(); - long next = timestampAndSequence.incrementAndGet(); - long timestampWithSequence = next & timestampAndSequenceMask; - return workerId | timestampWithSequence; - } - - /** - * block current thread if the QPS of acquiring UUID is too high - * that current sequence space is exhausted - */ - private void waitIfNecessary() { - long currentWithSequence = timestampAndSequence.get(); - long current = currentWithSequence >>> sequenceBits; - long newest = getNewestTimestamp(); - if (current >= newest) { - try { - Thread.sleep(5); - } catch (InterruptedException ignore) { - // don't care - } - } - } - - /** - * get newest timestamp relative to twepoch - */ - private long getNewestTimestamp() { - return System.currentTimeMillis() - twepoch; - } - - /** - * auto generate workerId, try using mac first, if failed, then randomly generate one - * @return workerId - */ - private long generateWorkerId() { - try { - return generateWorkerIdBaseOnMac(); - } catch (Exception e) { - return generateRandomWorkerId(); - } - } - - /** - * use lowest 10 bit of available MAC as workerId - * @return workerId - * @throws Exception when there is no available mac found - */ - private long generateWorkerIdBaseOnMac() throws Exception { - Enumeration all = NetworkInterface.getNetworkInterfaces(); - while (all.hasMoreElements()) { - NetworkInterface networkInterface = all.nextElement(); - boolean isLoopback = networkInterface.isLoopback(); - boolean isVirtual = networkInterface.isVirtual(); - if (isLoopback || isVirtual) { - continue; - } - byte[] mac = networkInterface.getHardwareAddress(); - return ((mac[4] & 0B11) << 8) | (mac[5] & 0xFF); - } - throw new RuntimeException("no available mac found"); - } - - /** - * randomly generate one as workerId - * @return workerId - */ - private long generateRandomWorkerId() { - return new Random().nextInt(maxWorkerId + 1); - } -} diff --git a/src/main/java/icu/funkye/redispike/util/UUIDGenerator.java b/src/main/java/icu/funkye/redispike/util/UUIDGenerator.java deleted file mode 100644 index bd36ff0..0000000 --- a/src/main/java/icu/funkye/redispike/util/UUIDGenerator.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 icu.funkye.redispike.util; - -/** - * The type Uuid generator. - */ -public class UUIDGenerator { - - private static volatile IdWorker idWorker; - - /** - * generate UUID using snowflake algorithm - * @return UUID - */ - public static long generateUUID() { - if (idWorker == null) { - synchronized (UUIDGenerator.class) { - if (idWorker == null) { - init(null); - } - } - } - return idWorker.nextId(); - } - - /** - * init IdWorker - * @param serverNode the server node id, consider as machine id in snowflake - */ - public static void init(Long serverNode) { - idWorker = new IdWorker(serverNode); - } - -} From 7886891aca96b2d052bc99414d8160d624d26861 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:17:49 +0800 Subject: [PATCH 15/31] test --- .../process/impl/CommandRequestProcessor.java | 1 - .../process/impl/DelRequestProcessor.java | 1 - .../process/impl/GetRequestProcessor.java | 1 - .../process/impl/HDelRequestProcessor.java | 1 - .../process/impl/HSetRequestProcessor.java | 1 - .../process/impl/KeysRequestProcessor.java | 18 ------------------ .../process/impl/SetRequestProcessor.java | 1 - .../protocol/response/BulkResponse.java | 2 -- 8 files changed, 26 deletions(-) diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/CommandRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/CommandRequestProcessor.java index 16f8fa7..1b3b811 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/CommandRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/CommandRequestProcessor.java @@ -16,7 +16,6 @@ */ package icu.funkye.redispike.handler.process.impl; -import java.nio.charset.StandardCharsets; import com.alipay.remoting.RemotingContext; import icu.funkye.redispike.handler.process.AbstractRedisRequestProcessor; import icu.funkye.redispike.protocol.RedisRequestCommandCode; diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java index 0cb4918..ee3078d 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/DelRequestProcessor.java @@ -16,7 +16,6 @@ */ package icu.funkye.redispike.handler.process.impl; -import java.nio.charset.StandardCharsets; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/GetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/GetRequestProcessor.java index 27748df..76b191b 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/GetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/GetRequestProcessor.java @@ -16,7 +16,6 @@ */ package icu.funkye.redispike.handler.process.impl; -import java.nio.charset.StandardCharsets; import com.aerospike.client.AerospikeException; import com.aerospike.client.Key; import com.aerospike.client.Record; diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/HDelRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/HDelRequestProcessor.java index 4238a9d..6b0ced4 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/HDelRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/HDelRequestProcessor.java @@ -16,7 +16,6 @@ */ package icu.funkye.redispike.handler.process.impl; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java index ff470c1..edea7c5 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java @@ -16,7 +16,6 @@ */ package icu.funkye.redispike.handler.process.impl; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import com.aerospike.client.AerospikeException; diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java index bab2054..2091138 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java @@ -16,37 +16,19 @@ */ package icu.funkye.redispike.handler.process.impl; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import com.aerospike.client.AerospikeException; -import com.aerospike.client.Bin; import com.aerospike.client.Key; import com.aerospike.client.Record; -import com.aerospike.client.Value; -import com.aerospike.client.listener.RecordListener; import com.aerospike.client.listener.RecordSequenceListener; import com.aerospike.client.policy.ScanPolicy; import com.alipay.remoting.RemotingContext; import com.alipay.remoting.util.StringUtils; -import com.alipay.sofa.common.profile.StringUtil; import icu.funkye.redispike.factory.AeroSpikeClientFactory; import icu.funkye.redispike.handler.process.AbstractRedisRequestProcessor; import icu.funkye.redispike.protocol.RedisRequestCommandCode; -import icu.funkye.redispike.protocol.request.GetRequest; import icu.funkye.redispike.protocol.request.KeysRequest; -import icu.funkye.redispike.util.IdWorker; import icu.funkye.redispike.util.IntegerUtils; -import icu.funkye.redispike.util.UUIDGenerator; public class KeysRequestProcessor extends AbstractRedisRequestProcessor { ScanPolicy scanPolicy = new ScanPolicy(client.getScanPolicyDefault()); diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java index 0235c25..9808cc3 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SetRequestProcessor.java @@ -16,7 +16,6 @@ */ package icu.funkye.redispike.handler.process.impl; -import java.nio.charset.StandardCharsets; import com.aerospike.client.AerospikeException; import com.aerospike.client.Bin; import com.aerospike.client.Key; diff --git a/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java b/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java index 46dfc12..cf1702b 100644 --- a/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java +++ b/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java @@ -18,8 +18,6 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import io.netty.buffer.ByteBuf; import icu.funkye.redispike.protocol.RedisResponse; From ea0c0e01f10385a2ebadc0b9f0c306c49bd3e1ef Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:24:34 +0800 Subject: [PATCH 16/31] test --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0f23f7a..df33ebc 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 1.2.9 1.3.6 3.8 - 4.6.0 + 4.4.20 From 12ab8423838f793f2d27c5623920cf94241967cc Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:30:07 +0800 Subject: [PATCH 17/31] test --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index df33ebc..ad5109a 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 1.2.9 1.3.6 3.8 - 4.4.20 + 5.3.0 From 66223917dbf7a0a05937d328b71b2a5fdfae83cf Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:32:23 +0800 Subject: [PATCH 18/31] test --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ad5109a..2d6a8b8 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 1.2.9 1.3.6 3.8 - 5.3.0 + 6.3.0 From 23c0c6f765c7ea4606748efe162a1d7c091b8803 Mon Sep 17 00:00:00 2001 From: jianbin Date: Mon, 8 Apr 2024 18:34:04 +0800 Subject: [PATCH 19/31] test --- .../redispike/handler/process/impl/KeysRequestProcessor.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java index 2091138..f73846c 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java @@ -54,10 +54,8 @@ public void handle(RemotingContext ctx, KeysRequest request) { @Override public void onRecord(Key key, Record record) throws AerospikeException { if (key != null) { - logger.info("userKey:{}", key); if (key.userKey != null) { String userKey = key.userKey.toString(); - logger.info("userKey:{}", userKey); if (all) { request.setResponse(userKey); } else if (left) { From 7c521c11f723bb1c0504d8a46aaebfc0825bcf3f Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 11:09:50 +0800 Subject: [PATCH 20/31] feature: support hgetall&hget protocol --- .github/workflows/build.yml | 7 +- README.md | 8 +-- pom.xml | 7 +- .../handler/RedisCommandHandler.java | 6 ++ .../process/impl/HGetAllRequestProcessor.java | 63 +++++++++++++++++ .../process/impl/HGetRequestProcessor.java | 66 +++++++++++++++++ .../process/impl/KeysRequestProcessor.java | 5 +- .../protocol/RedisCommandDecoder.java | 6 ++ .../protocol/request/HGetAllRequest.java | 52 ++++++++++++++ .../protocol/request/HGetRequest.java | 70 +++++++++++++++++++ .../protocol/request/KeysRequest.java | 10 ++- .../protocol/response/BulkResponse.java | 19 ++++- .../java/icu/funkye/redispike/ServerTest.java | 10 ++- 13 files changed, 316 insertions(+), 13 deletions(-) create mode 100644 src/main/java/icu/funkye/redispike/handler/process/impl/HGetAllRequestProcessor.java create mode 100644 src/main/java/icu/funkye/redispike/handler/process/impl/HGetRequestProcessor.java create mode 100644 src/main/java/icu/funkye/redispike/protocol/request/HGetAllRequest.java create mode 100644 src/main/java/icu/funkye/redispike/protocol/request/HGetRequest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0a6272b..cd7b488 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,8 +38,13 @@ jobs: - name: "Print maven version" run: ./mvnw -version - name: "Test, Check style, Check PMD, Check license with Maven and Java" + if: matrix.java == '8' + run: | + ./mvnw -T 4C clean test -Dasp-client.version=6.3.0 && sh ./tools/check_format.sh + - name: "Test with Maven and Java${{ matrix.java }}" + if: matrix.java != '8' run: | - ./mvnw -T 4C clean test && sh ./tools/check_format.sh + ./mvnw -T 4C clean test - name: "Codecov" if: matrix.java == '8' uses: codecov/codecov-action@v4.0.1 diff --git a/README.md b/README.md index d25749b..1587ee6 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,9 @@ Details can be found here: [redispike-proxy/src/test/java/icu/funkye/redispike/S | Hash | done | HSETNX only supports the key level, not the column level | | Scan | | | | List | | | -| Set | | | -| ZSet | | | -| keys | done | | - - +| Set | wait | | +| ZSet | wait | | +| keys | done | | ### Performance Test Report aerospike 3.x 2c4g redispike-proxy 2c4g: diff --git a/pom.xml b/pom.xml index 2d6a8b8..f737338 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 1.2.9 1.3.6 3.8 - 6.3.0 + 4.1.2 @@ -69,6 +69,11 @@ junit-jupiter ${junit-jupiter.version} + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + ${artifactId} diff --git a/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java b/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java index 426e06f..cf62c68 100644 --- a/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java +++ b/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java @@ -26,6 +26,8 @@ import com.alipay.remoting.RemotingProcessor; import icu.funkye.redispike.handler.process.impl.GetRequestProcessor; import icu.funkye.redispike.handler.process.impl.HDelRequestProcessor; +import icu.funkye.redispike.handler.process.impl.HGetAllRequestProcessor; +import icu.funkye.redispike.handler.process.impl.HGetRequestProcessor; import icu.funkye.redispike.handler.process.impl.HSetRequestProcessor; import icu.funkye.redispike.handler.process.impl.KeysRequestProcessor; import icu.funkye.redispike.handler.process.impl.SetRequestProcessor; @@ -57,6 +59,10 @@ public RedisCommandHandler() { processorMap.put(setRequestProcessor.getCmdCode().value(), setRequestProcessor); KeysRequestProcessor keysRequestProcessor = new KeysRequestProcessor(); processorMap.put(keysRequestProcessor.getCmdCode().value(), keysRequestProcessor); + HGetAllRequestProcessor hGetAllRequestProcessor = new HGetAllRequestProcessor(); + processorMap.put(hGetAllRequestProcessor.getCmdCode().value(), hGetAllRequestProcessor); + HGetRequestProcessor hGetRequestProcessor = new HGetRequestProcessor(); + processorMap.put(hGetRequestProcessor.getCmdCode().value(), hGetRequestProcessor); } @Override diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/HGetAllRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/HGetAllRequestProcessor.java new file mode 100644 index 0000000..809046b --- /dev/null +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/HGetAllRequestProcessor.java @@ -0,0 +1,63 @@ +/* + * 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 icu.funkye.redispike.handler.process.impl; + +import com.aerospike.client.AerospikeException; +import com.aerospike.client.Key; +import com.aerospike.client.Record; +import com.aerospike.client.listener.RecordListener; +import com.alipay.remoting.RemotingContext; +import com.alipay.sofa.common.profile.StringUtil; + +import icu.funkye.redispike.factory.AeroSpikeClientFactory; +import icu.funkye.redispike.handler.process.AbstractRedisRequestProcessor; +import icu.funkye.redispike.protocol.RedisRequestCommandCode; +import icu.funkye.redispike.protocol.request.HGetAllRequest; +import icu.funkye.redispike.protocol.request.HGetRequest; +import icu.funkye.redispike.util.IntegerUtils; + +public class HGetAllRequestProcessor extends AbstractRedisRequestProcessor { + + public HGetAllRequestProcessor() { + this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(HGetAllRequest.class.hashCode())); + } + + @Override + public void handle(RemotingContext ctx, HGetAllRequest request) { + Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); + client.get(AeroSpikeClientFactory.eventLoops.next(), new RecordListener() { + @Override + public void onSuccess(Key key, Record record) { + if (record == null) { + ctx.writeAndFlush(request.getResponse()); + return; + } + record.bins.forEach((k,v)-> { + request.setResponse(k); + request.setResponse(v.toString()); + }); + ctx.writeAndFlush(request.getResponse()); + } + + @Override + public void onFailure(AerospikeException ae) { + logger.error(ae.getMessage(), ae); + ctx.writeAndFlush(request.getResponse()); + } + }, client.getReadPolicyDefault(), key); + } +} diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/HGetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/HGetRequestProcessor.java new file mode 100644 index 0000000..782aea1 --- /dev/null +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/HGetRequestProcessor.java @@ -0,0 +1,66 @@ +/* + * 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 icu.funkye.redispike.handler.process.impl; + +import com.aerospike.client.AerospikeException; +import com.aerospike.client.Key; +import com.aerospike.client.Record; +import com.aerospike.client.listener.RecordListener; +import com.alipay.remoting.RemotingContext; +import com.alipay.sofa.common.profile.StringUtil; + +import icu.funkye.redispike.factory.AeroSpikeClientFactory; +import icu.funkye.redispike.handler.process.AbstractRedisRequestProcessor; +import icu.funkye.redispike.protocol.RedisRequestCommandCode; +import icu.funkye.redispike.protocol.request.HGetRequest; +import icu.funkye.redispike.util.IntegerUtils; + +public class HGetRequestProcessor extends AbstractRedisRequestProcessor { + + public HGetRequestProcessor() { + this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(HGetRequest.class.hashCode())); + } + + @Override + public void handle(RemotingContext ctx, HGetRequest request) { + if (request.getField() == null) { + ctx.writeAndFlush(request.getResponse()); + return; + } + Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); + client.get(AeroSpikeClientFactory.eventLoops.next(), new RecordListener() { + @Override + public void onSuccess(Key key, Record record) { + if (record == null) { + ctx.writeAndFlush(request.getResponse()); + return; + } + String value = record.getString(request.getField()); + if (StringUtil.isNotBlank(value)) { + request.setResponse(value); + } + ctx.writeAndFlush(request.getResponse()); + } + + @Override + public void onFailure(AerospikeException ae) { + logger.error(ae.getMessage(), ae); + ctx.writeAndFlush(request.getResponse()); + } + }, client.getReadPolicyDefault(), key, request.getField()); + } +} diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java index f73846c..e55d637 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/KeysRequestProcessor.java @@ -40,7 +40,10 @@ public KeysRequestProcessor() { @Override public void handle(RemotingContext ctx, KeysRequest request) { - + if (StringUtils.isBlank(request.getPattern())) { + ctx.writeAndFlush(request.getResponse()); + return; + } boolean all = StringUtils.equals(request.getPattern(), "*"); boolean left = request.getPattern().startsWith("*"); if (left) { diff --git a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java index 4cc0a65..2cc08b4 100644 --- a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java +++ b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java @@ -21,6 +21,8 @@ import java.util.List; import com.alipay.remoting.CommandDecoder; import icu.funkye.redispike.protocol.request.HDelRequest; +import icu.funkye.redispike.protocol.request.HGetAllRequest; +import icu.funkye.redispike.protocol.request.HGetRequest; import icu.funkye.redispike.protocol.request.HSetRequest; import icu.funkye.redispike.protocol.request.KeysRequest; import io.netty.buffer.ByteBuf; @@ -79,6 +81,10 @@ private RedisRequest convert2RedisRequest(List params) { case "del": params.remove(0); return new DelRequest(params); + case "hget": + return new HGetRequest(params.get(1), params.size() > 2 ? params.get(2) : null); + case "hgetall": + return new HGetAllRequest(params.get(1)); default: return null; } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/HGetAllRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/HGetAllRequest.java new file mode 100644 index 0000000..360a716 --- /dev/null +++ b/src/main/java/icu/funkye/redispike/protocol/request/HGetAllRequest.java @@ -0,0 +1,52 @@ +/* + * 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 icu.funkye.redispike.protocol.request; + +import java.util.ArrayList; +import icu.funkye.redispike.protocol.RedisRequest; +import icu.funkye.redispike.protocol.RedisResponse; +import icu.funkye.redispike.protocol.response.BulkResponse; + +public class HGetAllRequest implements RedisRequest { + + String key; + + BulkResponse response = new BulkResponse(new ArrayList<>()); + + public HGetAllRequest(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + @Override + public void setResponse(String data) { + this.response.appender(data); + } + + @Override + public RedisResponse getResponse() { + return response; + } + + @Override + public String toString() { + return "GetRequest{" + "key='" + key + '\'' + ", response=" + response + '}'; + } +} diff --git a/src/main/java/icu/funkye/redispike/protocol/request/HGetRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/HGetRequest.java new file mode 100644 index 0000000..fa5f47f --- /dev/null +++ b/src/main/java/icu/funkye/redispike/protocol/request/HGetRequest.java @@ -0,0 +1,70 @@ +/* + * 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 icu.funkye.redispike.protocol.request; + +import com.alipay.remoting.util.StringUtils; +import icu.funkye.redispike.protocol.RedisRequest; +import icu.funkye.redispike.protocol.RedisResponse; +import icu.funkye.redispike.protocol.response.BulkResponse; + +public class HGetRequest implements RedisRequest { + + final String key; + + final String field; + + BulkResponse response = new BulkResponse(); + + public HGetRequest(String key, String field) { + this.key = key; + if (StringUtils.isBlank(field)) { + response.setError("ERR wrong number of arguments for 'hget' command"); + } + this.field = field; + } + + public String getKey() { + return key; + } + + @Override + public void setResponse(String data) { + this.response.setData(data); + } + + @Override + public RedisResponse getResponse() { + return response; + } + + public String getField() { + return field; + } + + public void setResponse(BulkResponse response) { + this.response = response; + } + + public void setError(String errorMsg) { + this.response.setError(errorMsg); + } + + @Override + public String toString() { + return "HGetRequest{" + "key='" + key + '\'' + ", field='" + field + '\'' + ", response=" + response + '}'; + } +} diff --git a/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java index 59f5dad..01cda58 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java @@ -36,8 +36,14 @@ public class KeysRequest implements RedisRequest { public KeysRequest(List params) { this.originalCommand = params.get(0); - this.pattern = params.get(1); - this.response = new BulkResponse(new ArrayList<>()); + + if (params.size() != 3) { + this.response = new BulkResponse(); + this.response.setError("ERR wrong number of arguments for 'keys' command"); + } else { + this.response = new BulkResponse(new ArrayList<>()); + this.pattern = params.get(1); + } } @Override diff --git a/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java b/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java index cf1702b..6fe4b38 100644 --- a/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java +++ b/src/main/java/icu/funkye/redispike/protocol/response/BulkResponse.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.List; +import com.alipay.remoting.util.StringUtils; import io.netty.buffer.ByteBuf; import icu.funkye.redispike.protocol.RedisResponse; @@ -36,6 +37,8 @@ public class BulkResponse implements RedisResponse { private String data; + private String error; + public BulkResponse(List list) { this.list = list; } @@ -56,7 +59,13 @@ public void setData(String data) { } @Override - public void write(ByteBuf out) throws IOException { + public void write(ByteBuf out) { + if (StringUtils.isNotBlank(error)) { + out.writeByte(ERROR_PREFIX); + out.writeBytes(error.getBytes(StandardCharsets.UTF_8)); + out.writeBytes(CRLF); + return; + } if (list != null) { out.writeByte(ARRAY_PREFIX); out.writeBytes(String.valueOf(list.size()).getBytes(StandardCharsets.UTF_8)); @@ -81,6 +90,14 @@ public void write(ByteBuf out) throws IOException { } } + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + @Override public String toString() { return "BulkResponse{" + "list=" + list + '}'; diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index 2f93efa..67a0b27 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -33,6 +33,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import icu.funkye.redispike.factory.AeroSpikeClientFactory; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; @@ -49,12 +50,14 @@ public class ServerTest { @BeforeAll public static void init() throws ParseException { server = new Server(); - server.start("-p 6789".split(" ")); + server.start("-th 10.58.10.103 -tp 3000 -n test -s tdkv-test -TU tongdun-admin1 -TP xxxzzz123 -p 6789" + .split(" ")); JedisPooledFactory.getJedisPoolInstance("127.0.0.1", 6789); aspClient = AeroSpikeClientFactory.getClient(); } @Test + @DisabledIfSystemProperty(named = "asp-client.version", matches = "6.3.0") public void testhKeys() { List keys = new ArrayList<>(); for (int i = 0; i < 2; i++) { @@ -68,7 +71,6 @@ public void testhKeys() { Assertions.assertEquals(result.size(), 0); result = jedis.keys("*"); Assertions.assertNotEquals(result.size(), 0); - result = jedis.keys("*"); jedis.set("abc123", "123"); result = jedis.keys("abc*"); Assertions.assertEquals(result.size(), 1); @@ -98,6 +100,10 @@ public void testhHash() { Assertions.assertEquals(result, 1); result = jedis.hsetnx(key, "f", "g"); Assertions.assertEquals(result, 0); + String value = jedis.hget(key, "f"); + Assertions.assertEquals(value, "g"); + map = jedis.hgetAll(key); + Assertions.assertEquals(map.size(), 1); result = jedis.del(key); Assertions.assertEquals(result, 1); } From 36ef267521f212dbbb25f951abad0edc505cf789 Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 11:11:01 +0800 Subject: [PATCH 21/31] feature: support hgetall&hget protocol --- src/test/java/icu/funkye/redispike/ServerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index 67a0b27..6f65a94 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -57,7 +57,7 @@ public static void init() throws ParseException { } @Test - @DisabledIfSystemProperty(named = "asp-client.version", matches = "6.3.0") + @DisabledIfSystemProperty(named = "asp-client.version", matches = "4.1.2") public void testhKeys() { List keys = new ArrayList<>(); for (int i = 0; i < 2; i++) { From a1a8784f9508c63fcf74f2bd505e474d9027cd4c Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 11:12:57 +0800 Subject: [PATCH 22/31] feature: support hgetall&hget protocol --- src/test/java/icu/funkye/redispike/ServerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index 6f65a94..a8b1415 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -50,7 +50,7 @@ public class ServerTest { @BeforeAll public static void init() throws ParseException { server = new Server(); - server.start("-th 10.58.10.103 -tp 3000 -n test -s tdkv-test -TU tongdun-admin1 -TP xxxzzz123 -p 6789" + server.start("-p 6789" .split(" ")); JedisPooledFactory.getJedisPoolInstance("127.0.0.1", 6789); aspClient = AeroSpikeClientFactory.getClient(); From 4882e3614d01c250829bd25c1a174596789fa35c Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 11:16:24 +0800 Subject: [PATCH 23/31] feature: support hgetall&hget protocol --- .github/workflows/build.yml | 2 +- .../icu/funkye/redispike/protocol/request/KeysRequest.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd7b488..b989dbd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: - name: "Test with Maven and Java${{ matrix.java }}" if: matrix.java != '8' run: | - ./mvnw -T 4C clean test + ./mvnw -T 4C clean test -Dasp-client.version=4.1.2 - name: "Codecov" if: matrix.java == '8' uses: codecov/codecov-action@v4.0.1 diff --git a/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java index 01cda58..39240c0 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/KeysRequest.java @@ -36,8 +36,7 @@ public class KeysRequest implements RedisRequest { public KeysRequest(List params) { this.originalCommand = params.get(0); - - if (params.size() != 3) { + if (params.size() != 2) { this.response = new BulkResponse(); this.response.setError("ERR wrong number of arguments for 'keys' command"); } else { From ca3fe6c4212f4038202edee635498e198772bffd Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 11:19:45 +0800 Subject: [PATCH 24/31] feature: support hgetall&hget protocol --- src/test/java/icu/funkye/redispike/ServerTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index a8b1415..f7c34df 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -50,8 +50,7 @@ public class ServerTest { @BeforeAll public static void init() throws ParseException { server = new Server(); - server.start("-p 6789" - .split(" ")); + server.start("-p 6789".split(" ")); JedisPooledFactory.getJedisPoolInstance("127.0.0.1", 6789); aspClient = AeroSpikeClientFactory.getClient(); } From fd1b0408f7c673fbe2662e194703a5a122b7ee9b Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 16:59:42 +0800 Subject: [PATCH 25/31] feature: support sadd&smemebers&spop protocol --- README.md | 20 ++--- codecov.yml | 2 +- .../handler/RedisCommandHandler.java | 9 +++ .../process/impl/HSetRequestProcessor.java | 8 +- .../process/impl/SAddRequestProcessor.java | 65 ++++++++++++++++ .../impl/SMembersRequestProcessor.java | 58 ++++++++++++++ .../process/impl/SPopRequestProcessor.java | 71 ++++++++++++++++++ .../protocol/RedisCommandDecoder.java | 14 +++- .../protocol/request/HGetAllRequest.java | 2 +- .../protocol/request/HSetRequest.java | 6 ++ .../protocol/request/SAddRequest.java | 75 +++++++++++++++++++ .../protocol/request/SMembersRequest.java | 52 +++++++++++++ .../protocol/request/SPopRequest.java | 72 ++++++++++++++++++ src/main/resources/logback.xml | 25 +------ src/main/resources/lua/spop.lua | 29 +++++++ .../java/icu/funkye/redispike/ServerTest.java | 27 ++++++- 16 files changed, 493 insertions(+), 42 deletions(-) create mode 100644 src/main/java/icu/funkye/redispike/handler/process/impl/SAddRequestProcessor.java create mode 100644 src/main/java/icu/funkye/redispike/handler/process/impl/SMembersRequestProcessor.java create mode 100644 src/main/java/icu/funkye/redispike/handler/process/impl/SPopRequestProcessor.java create mode 100644 src/main/java/icu/funkye/redispike/protocol/request/SAddRequest.java create mode 100644 src/main/java/icu/funkye/redispike/protocol/request/SMembersRequest.java create mode 100644 src/main/java/icu/funkye/redispike/protocol/request/SPopRequest.java create mode 100644 src/main/resources/lua/spop.lua diff --git a/README.md b/README.md index 1587ee6..26c8a09 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# redis2asp +# redispike-proxy High-performance Aerospike proxy for the Redis protocold ### compatibility @@ -10,15 +10,15 @@ Redis 3.x - 7.x Details can be found here: [redispike-proxy/src/test/java/icu/funkye/redispike/ServerTest.java at main · funky-eyes/redispike-proxy (github.com)](https://github.com/funky-eyes/redispike-proxy/blob/main/src/test/java/icu/funkye/redispike/ServerTest.java) -| feature | support | note | -|---------|---------|------| -| String | done | | -| Hash | done | HSETNX only supports the key level, not the column level | -| Scan | | | -| List | | | -| Set | wait | | -| ZSet | wait | | -| keys | done | | +| feature | support | note | +|---------|-----------------------------------------------------------|----------------------------------------------------------| +| String | done | | +| Hash | done | hsetnx only supports the key level, not the column level | +| Scan | | | +| List | | | +| Set | sadd done
spop done
smembers done
other wait | | +| ZSet | wait | | +| keys | done | | ### Performance Test Report aerospike 3.x 2c4g redispike-proxy 2c4g: diff --git a/codecov.yml b/codecov.yml index a9a1762..0cbafe4 100644 --- a/codecov.yml +++ b/codecov.yml @@ -22,7 +22,7 @@ coverage: patch: no project: default: - threshold: 1% + threshold: 5% if_not_found: success changes: no precision: 2 diff --git a/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java b/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java index cf62c68..f37d18f 100644 --- a/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java +++ b/src/main/java/icu/funkye/redispike/handler/RedisCommandHandler.java @@ -30,9 +30,12 @@ import icu.funkye.redispike.handler.process.impl.HGetRequestProcessor; import icu.funkye.redispike.handler.process.impl.HSetRequestProcessor; import icu.funkye.redispike.handler.process.impl.KeysRequestProcessor; +import icu.funkye.redispike.handler.process.impl.SPopRequestProcessor; import icu.funkye.redispike.handler.process.impl.SetRequestProcessor; import icu.funkye.redispike.handler.process.impl.CommandRequestProcessor; import icu.funkye.redispike.handler.process.impl.DelRequestProcessor; +import icu.funkye.redispike.handler.process.impl.SAddRequestProcessor; +import icu.funkye.redispike.handler.process.impl.SMembersRequestProcessor; import icu.funkye.redispike.protocol.RedisRequest; import icu.funkye.redispike.protocol.response.BulkResponse; import org.slf4j.Logger; @@ -63,6 +66,12 @@ public RedisCommandHandler() { processorMap.put(hGetAllRequestProcessor.getCmdCode().value(), hGetAllRequestProcessor); HGetRequestProcessor hGetRequestProcessor = new HGetRequestProcessor(); processorMap.put(hGetRequestProcessor.getCmdCode().value(), hGetRequestProcessor); + SMembersRequestProcessor smembersRequestProcessor = new SMembersRequestProcessor(); + processorMap.put(smembersRequestProcessor.getCmdCode().value(), smembersRequestProcessor); + SAddRequestProcessor sAddRequestProcessor = new SAddRequestProcessor(); + processorMap.put(sAddRequestProcessor.getCmdCode().value(), sAddRequestProcessor); + SPopRequestProcessor sPopRequestProcessor = new SPopRequestProcessor(); + processorMap.put(sPopRequestProcessor.getCmdCode().value(), sPopRequestProcessor); } @Override diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java index edea7c5..a2c3b7e 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/HSetRequestProcessor.java @@ -33,8 +33,12 @@ import icu.funkye.redispike.util.IntegerUtils; public class HSetRequestProcessor extends AbstractRedisRequestProcessor { + WritePolicy defaultWritePolicy; + public HSetRequestProcessor() { this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(HSetRequest.class.hashCode())); + this.defaultWritePolicy = client.getWritePolicyDefault(); + this.defaultWritePolicy.sendKey = true; } @Override @@ -44,10 +48,10 @@ public void handle(RemotingContext ctx, HSetRequest request) { request.getKv().forEach((k, v) -> list.add(new Bin(k, v))); WritePolicy writePolicy; if (request.getOperate() != null && request.getOperate() == Operate.NX) { - writePolicy = new WritePolicy(client.getWritePolicyDefault()); + writePolicy = new WritePolicy(defaultWritePolicy); writePolicy.recordExistsAction = RecordExistsAction.CREATE_ONLY; } else { - writePolicy = client.getWritePolicyDefault(); + writePolicy = defaultWritePolicy; } client.put(AeroSpikeClientFactory.eventLoops.next(), new WriteListener() { @Override diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SAddRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SAddRequestProcessor.java new file mode 100644 index 0000000..5dd1f4f --- /dev/null +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SAddRequestProcessor.java @@ -0,0 +1,65 @@ +/* + * 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 icu.funkye.redispike.handler.process.impl; + +import java.util.ArrayList; +import java.util.List; + +import com.aerospike.client.AerospikeException; +import com.aerospike.client.Bin; +import com.aerospike.client.Key; +import com.aerospike.client.listener.WriteListener; +import com.aerospike.client.policy.WritePolicy; +import com.alipay.remoting.RemotingContext; + +import icu.funkye.redispike.factory.AeroSpikeClientFactory; +import icu.funkye.redispike.handler.process.AbstractRedisRequestProcessor; +import icu.funkye.redispike.protocol.RedisRequestCommandCode; +import icu.funkye.redispike.protocol.request.SAddRequest; +import icu.funkye.redispike.util.IntegerUtils; + +public class SAddRequestProcessor extends AbstractRedisRequestProcessor { + WritePolicy defaultWritePolicy; + + public SAddRequestProcessor() { + this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(SAddRequest.class.hashCode())); + this.defaultWritePolicy = client.getWritePolicyDefault(); + this.defaultWritePolicy.sendKey = true; + } + + @Override + public void handle(RemotingContext ctx, SAddRequest request) { + Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); + List list = new ArrayList<>(); + for (String field : request.getFields()) { + list.add(new Bin(field, "")); + } + client.put(AeroSpikeClientFactory.eventLoops.next(), new WriteListener() { + @Override + public void onSuccess(Key key) { + request.setResponse(String.valueOf(request.getFields().size())); + ctx.writeAndFlush(request.getResponse()); + } + + @Override + public void onFailure(AerospikeException ae) { + logger.error(ae.getMessage(), ae); + ctx.writeAndFlush(request.getResponse()); + } + }, defaultWritePolicy, key, list.toArray(new Bin[0])); + } +} diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SMembersRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SMembersRequestProcessor.java new file mode 100644 index 0000000..ea9a250 --- /dev/null +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SMembersRequestProcessor.java @@ -0,0 +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 icu.funkye.redispike.handler.process.impl; + +import com.aerospike.client.AerospikeException; +import com.aerospike.client.Key; +import com.aerospike.client.Record; +import com.aerospike.client.listener.RecordListener; +import com.alipay.remoting.RemotingContext; + +import icu.funkye.redispike.factory.AeroSpikeClientFactory; +import icu.funkye.redispike.handler.process.AbstractRedisRequestProcessor; +import icu.funkye.redispike.protocol.RedisRequestCommandCode; +import icu.funkye.redispike.protocol.request.SMembersRequest; +import icu.funkye.redispike.util.IntegerUtils; + +public class SMembersRequestProcessor extends AbstractRedisRequestProcessor { + + public SMembersRequestProcessor() { + this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(SMembersRequest.class.hashCode())); + } + + @Override + public void handle(RemotingContext ctx, SMembersRequest request) { + Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); + client.get(AeroSpikeClientFactory.eventLoops.next(), new RecordListener() { + @Override + public void onSuccess(Key key, Record record) { + if (record == null) { + ctx.writeAndFlush(request.getResponse()); + return; + } + record.bins.keySet().forEach(request::setResponse); + ctx.writeAndFlush(request.getResponse()); + } + + @Override + public void onFailure(AerospikeException ae) { + logger.error(ae.getMessage(), ae); + ctx.writeAndFlush(request.getResponse()); + } + }, client.getReadPolicyDefault(), key); + } +} diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SPopRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SPopRequestProcessor.java new file mode 100644 index 0000000..50458ac --- /dev/null +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SPopRequestProcessor.java @@ -0,0 +1,71 @@ +/* + * 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 icu.funkye.redispike.handler.process.impl; + +import java.util.List; +import java.util.Objects; + +import com.aerospike.client.AerospikeException; +import com.aerospike.client.Key; +import com.aerospike.client.Language; +import com.aerospike.client.Value; +import com.aerospike.client.listener.ExecuteListener; +import com.aerospike.client.task.RegisterTask; +import com.alipay.remoting.RemotingContext; + +import icu.funkye.redispike.factory.AeroSpikeClientFactory; +import icu.funkye.redispike.handler.process.AbstractRedisRequestProcessor; +import icu.funkye.redispike.protocol.RedisRequestCommandCode; +import icu.funkye.redispike.protocol.request.SPopRequest; +import icu.funkye.redispike.util.IntegerUtils; + +public class SPopRequestProcessor extends AbstractRedisRequestProcessor { + String luaScriptPath = Objects.requireNonNull(this.getClass().getClassLoader().getResource("lua/spop.lua")) + .getPath(); + + public SPopRequestProcessor() { + this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(SPopRequest.class.hashCode())); + RegisterTask task = client.register(null, SPopRequestProcessor.class.getClassLoader(), "lua/spop.lua", + "spop.lua", Language.LUA); + task.waitTillComplete(); + } + + @Override + public void handle(RemotingContext ctx, SPopRequest request) { + // Call the Lua script + Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, request.getKey()); + client.execute(AeroSpikeClientFactory.eventLoops.next(), new ExecuteListener() { + @Override + public void onSuccess(Key key, Object obj) { + if (obj instanceof String) { + String[] response = ((String) obj).split(","); + for (String s : response) { + request.setResponse(s); + } + } + ctx.writeAndFlush(request.getResponse()); + } + + @Override + public void onFailure(AerospikeException exception) { + logger.error(exception.getMessage(), exception); + ctx.writeAndFlush(request.getResponse()); + } + }, client.getWritePolicyDefault(), key, "spop", "random_delete_bins", request.getCount() == null ? Value.get(1) + : Value.get(request.getCount())); + } +} diff --git a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java index 2cc08b4..b235bff 100644 --- a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java +++ b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java @@ -25,6 +25,9 @@ import icu.funkye.redispike.protocol.request.HGetRequest; import icu.funkye.redispike.protocol.request.HSetRequest; import icu.funkye.redispike.protocol.request.KeysRequest; +import icu.funkye.redispike.protocol.request.SAddRequest; +import icu.funkye.redispike.protocol.request.SMembersRequest; +import icu.funkye.redispike.protocol.request.SPopRequest; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.DecoderException; @@ -58,8 +61,8 @@ public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { private RedisRequest convert2RedisRequest(List params) { String cmd = params.get(0); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("cmd: {}", params); + if (LOGGER.isInfoEnabled()) { + LOGGER.info("cmd: {}", params); } switch (cmd) { case "hdel": @@ -85,6 +88,13 @@ private RedisRequest convert2RedisRequest(List params) { return new HGetRequest(params.get(1), params.size() > 2 ? params.get(2) : null); case "hgetall": return new HGetAllRequest(params.get(1)); + case "sadd": + return new SAddRequest(params); + case "smembers": + return new SMembersRequest(params.get(1)); + case "spop": + params.remove(0); + return new SPopRequest(params.remove(0), params.size() > 0 ? Integer.parseInt(params.get(0)) : null); default: return null; } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/HGetAllRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/HGetAllRequest.java index 360a716..6d049dd 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/HGetAllRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/HGetAllRequest.java @@ -47,6 +47,6 @@ public RedisResponse getResponse() { @Override public String toString() { - return "GetRequest{" + "key='" + key + '\'' + ", response=" + response + '}'; + return "HGetAllRequest{" + "key='" + key + '\'' + ", response=" + response + '}'; } } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/HSetRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/HSetRequest.java index 42fdb2e..265d1a2 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/HSetRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/HSetRequest.java @@ -82,4 +82,10 @@ public void setResponse(RedisResponse response) { public String getKey() { return key; } + + @Override + public String toString() { + return "HSetRequest{" + "originalCommand='" + originalCommand + '\'' + ", key='" + key + '\'' + ", kv=" + kv + + ", operate=" + operate + ", response=" + response + '}'; + } } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/SAddRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/SAddRequest.java new file mode 100644 index 0000000..4f999ae --- /dev/null +++ b/src/main/java/icu/funkye/redispike/protocol/request/SAddRequest.java @@ -0,0 +1,75 @@ +/* + * 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 icu.funkye.redispike.protocol.request; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import icu.funkye.redispike.protocol.RedisRequest; +import icu.funkye.redispike.protocol.RedisResponse; +import icu.funkye.redispike.protocol.response.IntegerResponse; + +public class SAddRequest implements RedisRequest { + + String key; + + Set fields; + + IntegerResponse response = new IntegerResponse(); + + public SAddRequest(List params) { + params.remove(0); + this.key = params.remove(0); + this.fields = new HashSet<>(params); + } + + @Override + public void setResponse(String data) { + this.response.setData(data); + } + + @Override + public RedisResponse getResponse() { + return response; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Set getFields() { + return fields; + } + + public void setFields(Set fields) { + this.fields = fields; + } + + public void setResponse(IntegerResponse response) { + this.response = response; + } + + @Override + public String toString() { + return "SAddRequest{" + "key='" + key + '\'' + ", fields=" + fields + ", response=" + response + '}'; + } +} diff --git a/src/main/java/icu/funkye/redispike/protocol/request/SMembersRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/SMembersRequest.java new file mode 100644 index 0000000..d421426 --- /dev/null +++ b/src/main/java/icu/funkye/redispike/protocol/request/SMembersRequest.java @@ -0,0 +1,52 @@ +/* + * 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 icu.funkye.redispike.protocol.request; + +import java.util.ArrayList; +import icu.funkye.redispike.protocol.RedisRequest; +import icu.funkye.redispike.protocol.RedisResponse; +import icu.funkye.redispike.protocol.response.BulkResponse; + +public class SMembersRequest implements RedisRequest { + + String key; + + BulkResponse response = new BulkResponse(new ArrayList<>()); + + public SMembersRequest(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + @Override + public void setResponse(String data) { + this.response.setData(data); + } + + @Override + public RedisResponse getResponse() { + return response; + } + + @Override + public String toString() { + return "SMembersRequest{" + "key='" + key + '\'' + ", response=" + response + '}'; + } +} diff --git a/src/main/java/icu/funkye/redispike/protocol/request/SPopRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/SPopRequest.java new file mode 100644 index 0000000..2001d55 --- /dev/null +++ b/src/main/java/icu/funkye/redispike/protocol/request/SPopRequest.java @@ -0,0 +1,72 @@ +/* + * 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 icu.funkye.redispike.protocol.request; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import icu.funkye.redispike.protocol.RedisRequest; +import icu.funkye.redispike.protocol.RedisResponse; +import icu.funkye.redispike.protocol.response.BulkResponse; +import icu.funkye.redispike.protocol.response.IntegerResponse; + +public class SPopRequest implements RedisRequest { + + String key; + + Integer count; + + BulkResponse response; + + public SPopRequest(String key, Integer count) { + this.key = key; + this.count = count; + if (count != null) { + this.response = new BulkResponse(new ArrayList<>()); + } else { + this.response = new BulkResponse(); + } + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Integer getCount() { + return count; + } + + public void setCount(Integer count) { + this.count = count; + } + + @Override + public void setResponse(String data) { + this.response.setData(data); + } + + @Override + public RedisResponse getResponse() { + return response; + } + +} diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index fe8fd89..53da460 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -22,7 +22,7 @@ + value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/> @@ -48,28 +48,6 @@ - - - - WARN - ACCEPT - DENY - - ${LOG_FILE_PATH}/${APPLICATION_NAME:-redispike-proxy}redispike-proxy.warn.log - true - - ${LOG_FILE_PATH}/history/${APPLICATION_NAME:-redispike-proxy}redispike-proxy.warn.%d{yyyy-MM-dd}.%i.log.gz - 2GB - 7 - 7GB - true - - - ${FILE_LOG_PATTERN} - UTF-8 - - - @@ -94,7 +72,6 @@ - diff --git a/src/main/resources/lua/spop.lua b/src/main/resources/lua/spop.lua new file mode 100644 index 0000000..a8da6bf --- /dev/null +++ b/src/main/resources/lua/spop.lua @@ -0,0 +1,29 @@ +function random_delete_bins(rec, num_bins_to_delete) + if not aerospike:exists(rec) then + info("Record does not exist") + return nil + end + local bins = record.bin_names(rec) + local bin_count = #bins + if bin_count == 0 then + info("No bins found in record") + return nil + end + info("Record does 1") + num_bins_to_delete = math.min(num_bins_to_delete, bin_count) + info("Deleting " .. num_bins_to_delete .. " bins randomly") + info("Record does 2") + local bins_to_delete = {} + for i = 1, num_bins_to_delete do + local random_bin_index = math.random(#bins) + local bin_to_delete = table.remove(bins, random_bin_index) + info("Record does "..bin_to_delete) + rec[bin_to_delete] = nil + table.insert(bins_to_delete, bin_to_delete) + info("Record does "..i.." end") + end + aerospike:update(rec) + local str = table.concat(bins_to_delete, ", ") + info("Deleted bins: " .. str) + return str +end diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index f7c34df..5e1a4f8 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -50,14 +50,37 @@ public class ServerTest { @BeforeAll public static void init() throws ParseException { server = new Server(); - server.start("-p 6789".split(" ")); + server.start("-th 10.58.10.103 -tp 3000 -n test -s tdkv-test -TU tongdun-admin1 -TP xxxzzz123 -p 6789" + .split(" ")); JedisPooledFactory.getJedisPoolInstance("127.0.0.1", 6789); aspClient = AeroSpikeClientFactory.getClient(); } + @Test + public void TestSet() { + List keys = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + keys.add(String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue))); + } + String key = String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue)); + try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { + for (String value : keys) { + jedis.sadd(key, value); + } + Set list = jedis.smembers(key); + Assertions.assertNotEquals(list.size(), 3); + String value = jedis.spop(key); + Assertions.assertNotNull(value); + list = jedis.spop(key, 2); + Assertions.assertNotEquals(list.size(), 2); + list = jedis.smembers(key); + Assertions.assertEquals(list.size(), 0); + } + } + @Test @DisabledIfSystemProperty(named = "asp-client.version", matches = "4.1.2") - public void testhKeys() { + public void testKeys() { List keys = new ArrayList<>(); for (int i = 0; i < 2; i++) { keys.add(String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue))); From f9efb70fe3e87b76feb3a8e5e8263eb4ae30eb33 Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 17:12:27 +0800 Subject: [PATCH 26/31] feature: support sadd&smemebers&spop protocol --- src/test/java/icu/funkye/redispike/ServerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index 5e1a4f8..333a60f 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -50,7 +50,7 @@ public class ServerTest { @BeforeAll public static void init() throws ParseException { server = new Server(); - server.start("-th 10.58.10.103 -tp 3000 -n test -s tdkv-test -TU tongdun-admin1 -TP xxxzzz123 -p 6789" + server.start("-p 6789" .split(" ")); JedisPooledFactory.getJedisPoolInstance("127.0.0.1", 6789); aspClient = AeroSpikeClientFactory.getClient(); From eb002e4ebde94dd4241c24ba313cb59fc0c02be9 Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 17:19:49 +0800 Subject: [PATCH 27/31] test: add pippline test case --- .../protocol/RedisCommandDecoder.java | 4 +-- .../java/icu/funkye/redispike/ServerTest.java | 29 +++++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java index b235bff..6cf6e96 100644 --- a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java +++ b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java @@ -61,8 +61,8 @@ public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { private RedisRequest convert2RedisRequest(List params) { String cmd = params.get(0); - if (LOGGER.isInfoEnabled()) { - LOGGER.info("cmd: {}", params); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("cmd: {}", params); } switch (cmd) { case "hdel": diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index 333a60f..55afe8e 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -37,6 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; +import redis.clients.jedis.Pipeline; import redis.clients.jedis.params.SetParams; public class ServerTest { @@ -50,12 +51,36 @@ public class ServerTest { @BeforeAll public static void init() throws ParseException { server = new Server(); - server.start("-p 6789" - .split(" ")); + server.start("-p 6789".split(" ")); JedisPooledFactory.getJedisPoolInstance("127.0.0.1", 6789); aspClient = AeroSpikeClientFactory.getClient(); } + @Test + public void TestPippline() { + List keys = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + keys.add(String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue))); + } + String key = String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue)); + try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { + try(Pipeline pipeline = jedis.pipelined()) { + for (String value : keys) { + pipeline.hset(key, value,"b"); + pipeline.sync(); + } + } + jedis.del(key); + try(Pipeline pipeline = jedis.pipelined()) { + for (String value : keys) { + pipeline.set(key, value); + pipeline.sync(); + } + } + jedis.del(key); + } + } + @Test public void TestSet() { List keys = new ArrayList<>(); From 02e700aa3ff41ccaac2932d8e6806451dab6cf50 Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 17:20:52 +0800 Subject: [PATCH 28/31] test: add pippline test case --- .../handler/process/impl/SPopRequestProcessor.java | 4 ---- .../icu/funkye/redispike/protocol/request/SAddRequest.java | 4 ---- .../icu/funkye/redispike/protocol/request/SPopRequest.java | 7 ------- 3 files changed, 15 deletions(-) diff --git a/src/main/java/icu/funkye/redispike/handler/process/impl/SPopRequestProcessor.java b/src/main/java/icu/funkye/redispike/handler/process/impl/SPopRequestProcessor.java index 50458ac..2baa501 100644 --- a/src/main/java/icu/funkye/redispike/handler/process/impl/SPopRequestProcessor.java +++ b/src/main/java/icu/funkye/redispike/handler/process/impl/SPopRequestProcessor.java @@ -16,7 +16,6 @@ */ package icu.funkye.redispike.handler.process.impl; -import java.util.List; import java.util.Objects; import com.aerospike.client.AerospikeException; @@ -34,9 +33,6 @@ import icu.funkye.redispike.util.IntegerUtils; public class SPopRequestProcessor extends AbstractRedisRequestProcessor { - String luaScriptPath = Objects.requireNonNull(this.getClass().getClassLoader().getResource("lua/spop.lua")) - .getPath(); - public SPopRequestProcessor() { this.cmdCode = new RedisRequestCommandCode(IntegerUtils.hashCodeToShort(SPopRequest.class.hashCode())); RegisterTask task = client.register(null, SPopRequestProcessor.class.getClassLoader(), "lua/spop.lua", diff --git a/src/main/java/icu/funkye/redispike/protocol/request/SAddRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/SAddRequest.java index 4f999ae..4596dac 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/SAddRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/SAddRequest.java @@ -60,10 +60,6 @@ public Set getFields() { return fields; } - public void setFields(Set fields) { - this.fields = fields; - } - public void setResponse(IntegerResponse response) { this.response = response; } diff --git a/src/main/java/icu/funkye/redispike/protocol/request/SPopRequest.java b/src/main/java/icu/funkye/redispike/protocol/request/SPopRequest.java index 2001d55..ed3921b 100644 --- a/src/main/java/icu/funkye/redispike/protocol/request/SPopRequest.java +++ b/src/main/java/icu/funkye/redispike/protocol/request/SPopRequest.java @@ -17,13 +17,10 @@ package icu.funkye.redispike.protocol.request; import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import icu.funkye.redispike.protocol.RedisRequest; import icu.funkye.redispike.protocol.RedisResponse; import icu.funkye.redispike.protocol.response.BulkResponse; -import icu.funkye.redispike.protocol.response.IntegerResponse; public class SPopRequest implements RedisRequest { @@ -55,10 +52,6 @@ public Integer getCount() { return count; } - public void setCount(Integer count) { - this.count = count; - } - @Override public void setResponse(String data) { this.response.setData(data); From dde9cdd9c870fd3f84c0bb717c27247f26d2bf52 Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 17:26:45 +0800 Subject: [PATCH 29/31] test: add pippline test case --- src/test/java/icu/funkye/redispike/ServerTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/icu/funkye/redispike/ServerTest.java b/src/test/java/icu/funkye/redispike/ServerTest.java index 55afe8e..047f8c2 100644 --- a/src/test/java/icu/funkye/redispike/ServerTest.java +++ b/src/test/java/icu/funkye/redispike/ServerTest.java @@ -64,14 +64,14 @@ public void TestPippline() { } String key = String.valueOf(ThreadLocalRandom.current().nextInt(RandomValue)); try (Jedis jedis = JedisPooledFactory.getJedisInstance()) { - try(Pipeline pipeline = jedis.pipelined()) { + try (Pipeline pipeline = jedis.pipelined()) { for (String value : keys) { - pipeline.hset(key, value,"b"); + pipeline.hset(key, value, "b"); pipeline.sync(); } } jedis.del(key); - try(Pipeline pipeline = jedis.pipelined()) { + try (Pipeline pipeline = jedis.pipelined()) { for (String value : keys) { pipeline.set(key, value); pipeline.sync(); From 32200135fcf71bfaf0add47abf7e1b3e35446bb0 Mon Sep 17 00:00:00 2001 From: jianbin Date: Tue, 9 Apr 2024 17:28:23 +0800 Subject: [PATCH 30/31] test: add pippline test case --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 26c8a09..929089f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ High-performance Aerospike proxy for the Redis protocold ### compatibility Aerospike: 3.x - 7.x (8.x version has not been tested yet as there is no Docker image available currently) -Redis 3.x - 7.x + +Redis 3.x - latest ### support mode From 931af9ede5c33c6e6b64610dc36189dd920969f6 Mon Sep 17 00:00:00 2001 From: jianbin Date: Wed, 10 Apr 2024 10:55:39 +0800 Subject: [PATCH 31/31] optimize: add graalvm metadata --- pom.xml | 4 +- .../protocol/RedisCommandDecoder.java | 4 +- .../META-INF/native-image/jni-config.json | 26 ++ .../predefined-classes-config.json | 8 + .../META-INF/native-image/proxy-config.json | 2 + .../META-INF/native-image/reflect-config.json | 405 ++++++++++++++++++ .../native-image/resource-config.json | 23 + .../native-image/serialization-config.json | 8 + 8 files changed, 476 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/META-INF/native-image/jni-config.json create mode 100644 src/main/resources/META-INF/native-image/predefined-classes-config.json create mode 100644 src/main/resources/META-INF/native-image/proxy-config.json create mode 100644 src/main/resources/META-INF/native-image/reflect-config.json create mode 100644 src/main/resources/META-INF/native-image/resource-config.json create mode 100644 src/main/resources/META-INF/native-image/serialization-config.json diff --git a/pom.xml b/pom.xml index f737338..3f986f2 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ 0.3.1 5.8.2 1.6.0 - 1.2.9 + 1.2.13 1.3.6 3.8 4.1.2 @@ -26,7 +26,7 @@ org.slf4j slf4j-api - 1.7.6 + 1.7.36 ch.qos.logback diff --git a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java index b235bff..6cf6e96 100644 --- a/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java +++ b/src/main/java/icu/funkye/redispike/protocol/RedisCommandDecoder.java @@ -61,8 +61,8 @@ public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { private RedisRequest convert2RedisRequest(List params) { String cmd = params.get(0); - if (LOGGER.isInfoEnabled()) { - LOGGER.info("cmd: {}", params); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("cmd: {}", params); } switch (cmd) { case "hdel": diff --git a/src/main/resources/META-INF/native-image/jni-config.json b/src/main/resources/META-INF/native-image/jni-config.json new file mode 100644 index 0000000..cfcc74d --- /dev/null +++ b/src/main/resources/META-INF/native-image/jni-config.json @@ -0,0 +1,26 @@ +[ +{ + "name":"icu.funkye.redispike.ProxyMain", + "methods":[{"name":"main","parameterTypes":["java.lang.String[]"] }] +}, +{ + "name":"java.lang.Boolean", + "methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.lang.InternalError", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.lang.String", + "methods":[{"name":"lastIndexOf","parameterTypes":["int"] }, {"name":"substring","parameterTypes":["int"] }] +}, +{ + "name":"java.lang.System", + "methods":[{"name":"getProperty","parameterTypes":["java.lang.String"] }, {"name":"setProperty","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"sun.instrument.InstrumentationImpl", + "methods":[{"name":"","parameterTypes":["long","boolean","boolean","boolean"] }, {"name":"loadClassAndCallAgentmain","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"loadClassAndCallPremain","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"transform","parameterTypes":["java.lang.Module","java.lang.ClassLoader","java.lang.String","java.lang.Class","java.security.ProtectionDomain","byte[]","boolean"] }] +} +] diff --git a/src/main/resources/META-INF/native-image/predefined-classes-config.json b/src/main/resources/META-INF/native-image/predefined-classes-config.json new file mode 100644 index 0000000..0e79b2c --- /dev/null +++ b/src/main/resources/META-INF/native-image/predefined-classes-config.json @@ -0,0 +1,8 @@ +[ + { + "type":"agent-extracted", + "classes":[ + ] + } +] + diff --git a/src/main/resources/META-INF/native-image/proxy-config.json b/src/main/resources/META-INF/native-image/proxy-config.json new file mode 100644 index 0000000..0d4f101 --- /dev/null +++ b/src/main/resources/META-INF/native-image/proxy-config.json @@ -0,0 +1,2 @@ +[ +] diff --git a/src/main/resources/META-INF/native-image/reflect-config.json b/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 0000000..7e522be --- /dev/null +++ b/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,405 @@ +[ +{ + "name":"ch.qos.logback.classic.Level", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.classic.LoggerContext" +}, +{ + "name":"ch.qos.logback.classic.encoder.PatternLayoutEncoder", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.filter.LevelFilter", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setLevel","parameterTypes":["ch.qos.logback.classic.Level"] }] +}, +{ + "name":"ch.qos.logback.classic.pattern.ClassOfCallerConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.pattern.DateConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.pattern.LevelConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.pattern.LineOfCallerConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.pattern.LineSeparatorConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.pattern.LoggerConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.pattern.MessageConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.pattern.ThreadConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.core.ConsoleAppender", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.core.FileAppender", + "methods":[{"name":"setAppend","parameterTypes":["boolean"] }, {"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.OutputStreamAppender", + "methods":[{"name":"setEncoder","parameterTypes":["ch.qos.logback.core.encoder.Encoder"] }] +}, +{ + "name":"ch.qos.logback.core.UnsynchronizedAppenderBase", + "methods":[{"name":"addFilter","parameterTypes":["ch.qos.logback.core.filter.Filter"] }] +}, +{ + "name":"ch.qos.logback.core.encoder.Encoder", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.encoder.LayoutWrappingEncoder", + "methods":[{"name":"setCharset","parameterTypes":["java.nio.charset.Charset"] }, {"name":"setParent","parameterTypes":["ch.qos.logback.core.spi.ContextAware"] }] +}, +{ + "name":"ch.qos.logback.core.filter.AbstractMatcherFilter", + "methods":[{"name":"setOnMatch","parameterTypes":["ch.qos.logback.core.spi.FilterReply"] }, {"name":"setOnMismatch","parameterTypes":["ch.qos.logback.core.spi.FilterReply"] }] +}, +{ + "name":"ch.qos.logback.core.filter.Filter", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.pattern.PatternLayoutEncoderBase", + "methods":[{"name":"setPattern","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.rolling.RollingFileAppender", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setFile","parameterTypes":["java.lang.String"] }, {"name":"setRollingPolicy","parameterTypes":["ch.qos.logback.core.rolling.RollingPolicy"] }] +}, +{ + "name":"ch.qos.logback.core.rolling.RollingPolicy", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.rolling.RollingPolicyBase", + "methods":[{"name":"setFileNamePattern","parameterTypes":["java.lang.String"] }, {"name":"setParent","parameterTypes":["ch.qos.logback.core.FileAppender"] }] +}, +{ + "name":"ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setMaxFileSize","parameterTypes":["ch.qos.logback.core.util.FileSize"] }] +}, +{ + "name":"ch.qos.logback.core.rolling.TimeBasedRollingPolicy", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setCleanHistoryOnStart","parameterTypes":["boolean"] }, {"name":"setMaxHistory","parameterTypes":["int"] }, {"name":"setTotalSizeCap","parameterTypes":["ch.qos.logback.core.util.FileSize"] }] +}, +{ + "name":"ch.qos.logback.core.rolling.helper.DateTokenConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.core.rolling.helper.IntegerTokenConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.core.spi.ContextAware", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.spi.FilterReply", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.util.FileSize", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.alipay.remoting.ConnectionEventHandler", + "methods":[{"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"close","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"connect","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, {"name":"disconnect","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }] +}, +{ + "name":"com.alipay.remoting.ServerIdleHandler", + "methods":[{"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }] +}, +{ + "name":"com.alipay.remoting.codec.AbstractBatchDecoder", + "methods":[{"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }] +}, +{ + "name":"com.alipay.remoting.codec.ProtocolCodeBasedEncoder" +}, +{ + "name":"com.alipay.remoting.rpc.RpcHandler", + "methods":[{"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }] +}, +{ + "name":"com.alipay.remoting.rpc.RpcServer$1" +}, +{ + "name":"com.alipay.remoting.rpc.protocol.RpcProtocolDecoder" +}, +{ + "name":"com.intellij.rt.execution.application.AppMainV2$Agent", + "methods":[{"name":"premain","parameterTypes":["java.lang.String","java.lang.instrument.Instrumentation"] }] +}, +{ + "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"groovy.lang.Binding" +}, +{ + "name":"io.netty.bootstrap.ServerBootstrap$1" +}, +{ + "name":"io.netty.bootstrap.ServerBootstrap$ServerBootstrapAcceptor", + "methods":[{"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }] +}, +{ + "name":"io.netty.buffer.AbstractByteBufAllocator", + "queryAllDeclaredMethods":true +}, +{ + "name":"io.netty.buffer.AbstractReferenceCountedByteBuf", + "fields":[{"name":"refCnt"}] +}, +{ + "name":"io.netty.channel.AbstractChannelHandlerContext", + "fields":[{"name":"handlerState"}] +}, +{ + "name":"io.netty.channel.ChannelDuplexHandler", + "methods":[{"name":"bind","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, {"name":"close","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"connect","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, {"name":"deregister","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"disconnect","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"flush","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"read","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"write","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object","io.netty.channel.ChannelPromise"] }] +}, +{ + "name":"io.netty.channel.ChannelHandlerAdapter", + "methods":[{"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }] +}, +{ + "name":"io.netty.channel.ChannelInboundHandlerAdapter", + "methods":[{"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelWritabilityChanged","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }] +}, +{ + "name":"io.netty.channel.ChannelInitializer", + "methods":[{"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }] +}, +{ + "name":"io.netty.channel.ChannelOutboundBuffer", + "fields":[{"name":"totalPendingSize"}, {"name":"unwritable"}] +}, +{ + "name":"io.netty.channel.ChannelOutboundHandlerAdapter", + "methods":[{"name":"bind","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, {"name":"close","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"connect","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, {"name":"deregister","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"disconnect","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"flush","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"read","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }] +}, +{ + "name":"io.netty.channel.DefaultChannelConfig", + "fields":[{"name":"autoRead"}, {"name":"writeBufferWaterMark"}] +}, +{ + "name":"io.netty.channel.DefaultChannelPipeline", + "fields":[{"name":"estimatorHandle"}] +}, +{ + "name":"io.netty.channel.DefaultChannelPipeline$HeadContext", + "methods":[{"name":"bind","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, {"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelWritabilityChanged","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"close","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"connect","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, {"name":"deregister","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"disconnect","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, {"name":"flush","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"read","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, {"name":"write","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object","io.netty.channel.ChannelPromise"] }] +}, +{ + "name":"io.netty.channel.DefaultChannelPipeline$TailContext", + "methods":[{"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelWritabilityChanged","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }] +}, +{ + "name":"io.netty.channel.DefaultFileRegion" +}, +{ + "name":"io.netty.channel.epoll.NativeDatagramPacketArray$NativeDatagramPacket" +}, +{ + "name":"io.netty.channel.socket.nio.NioServerSocketChannel", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"io.netty.channel.unix.PeerCredentials" +}, +{ + "name":"io.netty.handler.codec.MessageToByteEncoder", + "methods":[{"name":"write","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object","io.netty.channel.ChannelPromise"] }] +}, +{ + "name":"io.netty.handler.timeout.IdleStateHandler", + "methods":[{"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, {"name":"write","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object","io.netty.channel.ChannelPromise"] }] +}, +{ + "name":"io.netty.util.AbstractReferenceCounted", + "fields":[{"name":"refCnt"}] +}, +{ + "name":"io.netty.util.DefaultAttributeMap", + "fields":[{"name":"attributes"}] +}, +{ + "name":"io.netty.util.DefaultAttributeMap$DefaultAttribute", + "fields":[{"name":"attributeMap"}] +}, +{ + "name":"io.netty.util.Recycler$DefaultHandle", + "fields":[{"name":"state"}] +}, +{ + "name":"io.netty.util.ReferenceCountUtil", + "queryAllDeclaredMethods":true +}, +{ + "name":"io.netty.util.ResourceLeakDetector$DefaultResourceLeak", + "fields":[{"name":"droppedRecords"}, {"name":"head"}] +}, +{ + "name":"io.netty.util.concurrent.DefaultPromise", + "fields":[{"name":"result"}] +}, +{ + "name":"io.netty.util.concurrent.SingleThreadEventExecutor", + "fields":[{"name":"state"}, {"name":"threadProperties"}] +}, +{ + "name":"io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields", + "fields":[{"name":"producerLimit"}] +}, +{ + "name":"io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields", + "fields":[{"name":"consumerIndex"}] +}, +{ + "name":"io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields", + "fields":[{"name":"producerIndex"}] +}, +{ + "name":"io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField", + "fields":[{"name":"consumerIndex"}] +}, +{ + "name":"io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField", + "fields":[{"name":"producerIndex"}] +}, +{ + "name":"io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField", + "fields":[{"name":"producerLimit"}] +}, +{ + "name":"java.io.FileDescriptor" +}, +{ + "name":"java.io.FilePermission" +}, +{ + "name":"java.lang.ProcessHandle", + "methods":[{"name":"current","parameterTypes":[] }, {"name":"pid","parameterTypes":[] }] +}, +{ + "name":"java.lang.RuntimePermission" +}, +{ + "name":"java.lang.Thread", + "fields":[{"name":"threadLocalRandomProbe"}] +}, +{ + "name":"java.lang.Throwable", + "methods":[{"name":"getSuppressed","parameterTypes":[] }] +}, +{ + "name":"java.net.NetPermission" +}, +{ + "name":"java.net.SocketPermission" +}, +{ + "name":"java.net.URLPermission", + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"java.nio.Bits", + "fields":[{"name":"MAX_MEMORY"}, {"name":"UNALIGNED"}] +}, +{ + "name":"java.nio.Buffer", + "fields":[{"name":"address"}] +}, +{ + "name":"java.nio.ByteBuffer", + "methods":[{"name":"alignedSlice","parameterTypes":["int"] }] +}, +{ + "name":"java.nio.DirectByteBuffer", + "methods":[{"name":"","parameterTypes":["long","long"] }] +}, +{ + "name":"java.nio.channels.FileChannel" +}, +{ + "name":"java.nio.channels.spi.SelectorProvider", + "methods":[{"name":"openServerSocketChannel","parameterTypes":["java.net.ProtocolFamily"] }, {"name":"openSocketChannel","parameterTypes":["java.net.ProtocolFamily"] }] +}, +{ + "name":"java.nio.charset.Charset", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.security.AllPermission" +}, +{ + "name":"java.security.SecurityPermission" +}, +{ + "name":"java.util.PropertyPermission" +}, +{ + "name":"java.util.concurrent.ForkJoinTask", + "fields":[{"name":"aux"}, {"name":"status"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicBoolean", + "fields":[{"name":"value"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicReference", + "fields":[{"name":"value"}] +}, +{ + "name":"java.util.concurrent.atomic.Striped64", + "fields":[{"name":"base"}, {"name":"cellsBusy"}] +}, +{ + "name":"javax.management.ObjectName" +}, +{ + "name":"javax.smartcardio.CardPermission" +}, +{ + "name":"jdk.internal.misc.Unsafe", + "methods":[{"name":"getUnsafe","parameterTypes":[] }] +}, +{ + "name":"sun.misc.Unsafe", + "fields":[{"name":"theUnsafe"}], + "methods":[{"name":"copyMemory","parameterTypes":["java.lang.Object","long","java.lang.Object","long","long"] }, {"name":"getAndAddLong","parameterTypes":["java.lang.Object","long","long"] }, {"name":"getAndSetObject","parameterTypes":["java.lang.Object","long","java.lang.Object"] }, {"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }, {"name":"storeFence","parameterTypes":[] }] +}, +{ + "name":"sun.nio.ch.SelectorImpl", + "fields":[{"name":"publicSelectedKeys"}, {"name":"selectedKeys"}] +} +] diff --git a/src/main/resources/META-INF/native-image/resource-config.json b/src/main/resources/META-INF/native-image/resource-config.json new file mode 100644 index 0000000..d32b397 --- /dev/null +++ b/src/main/resources/META-INF/native-image/resource-config.json @@ -0,0 +1,23 @@ +{ + "resources":{ + "includes":[{ + "pattern":"\\QMETA-INF/services/java.lang.System$LoggerFinder\\E" + }, { + "pattern":"\\QMETA-INF/services/java.nio.channels.spi.SelectorProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/java.time.zone.ZoneRulesProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/javax.xml.parsers.SAXParserFactory\\E" + }, { + "pattern":"\\Qcom/alipay/remoting/log/logback/log-conf.xml\\E" + }, { + "pattern":"\\Qlogback-test.xml\\E" + }, { + "pattern":"\\Qlogback.xml\\E" + }, { + "pattern":"\\Qlua/spop.lua\\E" + }, { + "pattern":"\\Qorg/slf4j/impl/StaticLoggerBinder.class\\E" + }]}, + "bundles":[] +} diff --git a/src/main/resources/META-INF/native-image/serialization-config.json b/src/main/resources/META-INF/native-image/serialization-config.json new file mode 100644 index 0000000..f3d7e06 --- /dev/null +++ b/src/main/resources/META-INF/native-image/serialization-config.json @@ -0,0 +1,8 @@ +{ + "types":[ + ], + "lambdaCapturingTypes":[ + ], + "proxies":[ + ] +}