Skip to content

Commit

Permalink
feature: support hgetall&hget protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
funky-eyes committed Apr 9, 2024
1 parent d9530e7 commit 7c521c1
Show file tree
Hide file tree
Showing 13 changed files with 316 additions and 13 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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/[email protected]
Expand Down
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
7 changes: 6 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<log.version>1.2.9</log.version>
<p3c-pmd.version>1.3.6</p3c-pmd.version>
<maven-pmd-plugin.version>3.8</maven-pmd-plugin.version>
<asp-client.version>6.3.0</asp-client.version>
<asp-client.version>4.1.2</asp-client.version>
</properties>
<dependencies>
<dependency>
Expand Down Expand Up @@ -69,6 +69,11 @@
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${artifactId}</finalName>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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<HGetAllRequest> {

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);
}
}
Original file line number Diff line number Diff line change
@@ -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<HGetRequest> {

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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -79,6 +81,10 @@ private RedisRequest<?> convert2RedisRequest(List<String> 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;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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> {

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<String> getResponse() {
return response;
}

@Override
public String toString() {
return "GetRequest{" + "key='" + key + '\'' + ", response=" + response + '}';
}
}
Original file line number Diff line number Diff line change
@@ -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<String> {

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<String> 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 + '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,14 @@ public class KeysRequest implements RedisRequest<String> {

public KeysRequest(List<String> 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
Expand Down
Loading

0 comments on commit 7c521c1

Please sign in to comment.