Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: support set nx ex protocol #4

Merged
merged 58 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
98000a3
support redis docker test case
funky-eyes Apr 5, 2024
7b9891b
support redis docker test case
funky-eyes Apr 5, 2024
e062af9
support redis docker test case
funky-eyes Apr 5, 2024
0db4bd7
support aerospike docker test case
funky-eyes Apr 5, 2024
d668a36
Merge branch 'main' into 0405
funky-eyes Apr 5, 2024
fb8d195
support aerospike docker test case
funky-eyes Apr 5, 2024
14ea00c
Merge branch '0405' of github.com:funky-eyes/redis2asp into 0405
funky-eyes Apr 5, 2024
180ecc3
support aerospike docker test case
funky-eyes Apr 5, 2024
328683a
test
funky-eyes Apr 5, 2024
f0bef65
test
funky-eyes Apr 5, 2024
f21a98d
test
funky-eyes Apr 5, 2024
f58edb3
test
funky-eyes Apr 5, 2024
3baf8b3
test
funky-eyes Apr 5, 2024
c601ed9
test
funky-eyes Apr 5, 2024
3591f5e
test
funky-eyes Apr 5, 2024
6c2571a
test
funky-eyes Apr 5, 2024
d7d0520
test
funky-eyes Apr 5, 2024
d9f9963
test
funky-eyes Apr 5, 2024
3e8754a
test
funky-eyes Apr 5, 2024
40c1cb7
test
funky-eyes Apr 5, 2024
bab50d7
test
funky-eyes Apr 5, 2024
c9963f9
test
funky-eyes Apr 5, 2024
03d69a0
test
funky-eyes Apr 5, 2024
b6c74fa
test
funky-eyes Apr 5, 2024
e18be22
test
funky-eyes Apr 5, 2024
516fe7b
test
funky-eyes Apr 5, 2024
4de142b
test
funky-eyes Apr 5, 2024
d379598
feature: support get protocol
funky-eyes Apr 6, 2024
95de3eb
Merge branch 'main' of github.com:funky-eyes/redis2asp into 0405
funky-eyes Apr 6, 2024
8e3cc19
test
funky-eyes Apr 6, 2024
a360ed0
test
funky-eyes Apr 6, 2024
55d8bb6
test
funky-eyes Apr 6, 2024
698b8b5
test
funky-eyes Apr 6, 2024
7d95579
test
funky-eyes Apr 6, 2024
09ea734
test
funky-eyes Apr 6, 2024
c1e5b7a
test
funky-eyes Apr 6, 2024
2419c62
test
funky-eyes Apr 6, 2024
ccf5038
test
funky-eyes Apr 6, 2024
72296b9
test
funky-eyes Apr 6, 2024
3a8eec8
test
funky-eyes Apr 6, 2024
7705601
test
funky-eyes Apr 6, 2024
7eb45e2
test
funky-eyes Apr 6, 2024
dc7ee09
test
funky-eyes Apr 6, 2024
5c56959
test
funky-eyes Apr 6, 2024
b3cc151
test
funky-eyes Apr 6, 2024
0753c0e
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
5d62dd7
update
funky-eyes Apr 6, 2024
ee3f828
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
f4b5e2e
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
fb3d40d
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
3121d16
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
e0fa942
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
90f8a15
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
920a462
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
5f11945
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
5562f0a
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
0e3ef93
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
85517e0
feature: support set nx ex protocol
funky-eyes Apr 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/main/java/org/redis2asp/protocol/RedisCommandDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,22 @@ public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
List<String> params = new ArrayList<>(length);
for (int i = 0; i < length; i++) {
String param = readParam(in);
params.add(param);
params.add(param.toLowerCase());
}
// convert to RedisRequest
out.add(convert2RedisRequest(params));
}

private RedisRequest<?> convert2RedisRequest(List<String> params) {
String cmd = params.get(0);
LOGGER.info("cmd: {}", cmd);
switch (cmd.toLowerCase()) {
LOGGER.info("cmd: {}", params);
switch (cmd) {
case "get":
return new GetRequest(params.get(1));
case "command":
return new CommandRequest();
case "set":
return new SetRequest(params.get(1), params.get(2));
return new SetRequest(params.get(1), params.get(2), params);
default:
return null;
}
Expand Down
61 changes: 56 additions & 5 deletions src/main/java/org/redis2asp/protocol/RedisCommandHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.aerospike.client.Record;
import com.aerospike.client.listener.RecordListener;
import com.aerospike.client.listener.WriteListener;
import com.aerospike.client.policy.RecordExistsAction;
import com.aerospike.client.policy.WritePolicy;
import com.alipay.remoting.CommandCode;
import com.alipay.remoting.CommandHandler;
import com.alipay.remoting.RemotingContext;
Expand All @@ -47,6 +49,7 @@ public class RedisCommandHandler implements CommandHandler {
public void handleCommand(RemotingContext ctx, Object msg) {
if (msg instanceof RedisRequest) {
RedisRequest<?> redisRequest = (RedisRequest) msg;
logger.info("redisRequest:{}", redisRequest);
if (redisRequest instanceof GetRequest) {
GetRequest getRequest = (GetRequest) redisRequest;
Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, getRequest.getKey());
Expand All @@ -67,7 +70,6 @@ public void onSuccess(Key key, Record record) {
@Override
public void onFailure(AerospikeException ae) {
logger.error(ae.getMessage(), ae);
getRequest.setResponse(ae.getMessage().getBytes(StandardCharsets.UTF_8));
ctx.writeAndFlush(redisRequest.getResponse());
}
}, client.getReadPolicyDefault(), key);
Expand All @@ -76,6 +78,57 @@ public void onFailure(AerospikeException ae) {
SetRequest setRequest = (SetRequest) redisRequest;
Bin bin = new Bin(setRequest.getKey(), setRequest.getValue());
Key key = new Key(AeroSpikeClientFactory.namespace, AeroSpikeClientFactory.set, setRequest.getKey());
WritePolicy writePolicy = null;
if (setRequest.getTtl() != null) {
writePolicy = new WritePolicy(client.getWritePolicyDefault());
if (setRequest.getTtlType() == SetRequest.TtlType.EX) {
writePolicy.expiration = setRequest.getTtl().intValue();
} else {
writePolicy.expiration = Integer.max((int) (setRequest.getTtl() / 1000), 1);
}
}
if (setRequest.getOperate() != null) {
if (writePolicy == null) {
writePolicy = new WritePolicy(client.getWritePolicyDefault());
}
if (setRequest.getOperate() == SetRequest.Operate.NX) {
writePolicy.recordExistsAction = RecordExistsAction.CREATE_ONLY;
}
if (setRequest.getOperate() == SetRequest.Operate.XX) {
client.get(null, new RecordListener() {
@Override
public void onSuccess(Key key, Record record) {
if (record == null) {
ctx.writeAndFlush(redisRequest.getResponse());
} else {
client.put(null, new WriteListener() {
@Override
public void onSuccess(Key key) {
setRequest.setResponse("OK".getBytes(StandardCharsets.UTF_8));
ctx.writeAndFlush(redisRequest.getResponse());
}

@Override
public void onFailure(AerospikeException ae) {
logger.error(ae.getMessage(), ae);
ctx.writeAndFlush(redisRequest.getResponse());
}
}, client.getWritePolicyDefault(), key, bin);
}
}

@Override
public void onFailure(AerospikeException ae) {
logger.error(ae.getMessage(), ae);
ctx.writeAndFlush(redisRequest.getResponse());
}
}, client.getReadPolicyDefault(), key);
return;
}
}
if (writePolicy == null) {
writePolicy = client.getWritePolicyDefault();
}
client.put(null, new WriteListener() {
@Override
public void onSuccess(Key key) {
Expand All @@ -85,10 +138,10 @@ public void onSuccess(Key key) {

@Override
public void onFailure(AerospikeException ae) {
setRequest.setResponse(ae.getMessage().getBytes(StandardCharsets.UTF_8));
logger.error(ae.getMessage(), ae);
ctx.writeAndFlush(redisRequest.getResponse());
}
}, client.getWritePolicyDefault(), key, bin);
}, writePolicy, key, bin);
}
if (redisRequest instanceof CommandRequest) {
CommandRequest commandRequest = (CommandRequest) redisRequest;
Expand All @@ -100,12 +153,10 @@ public void onFailure(AerospikeException ae) {

@Override
public void registerProcessor(CommandCode cmd, RemotingProcessor<?> processor) {

}

@Override
public void registerDefaultExecutor(ExecutorService executor) {

}

@Override
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/org/redis2asp/protocol/request/CommandRequest.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* 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 org.redis2asp.protocol.request;

import org.redis2asp.protocol.RedisRequest;
Expand All @@ -17,4 +33,9 @@ public RedisResponse<byte[]> getResponse() {
public void setResponse(byte[] data) {
response.setData(data);
}

@Override
public String toString() {
return "CommandRequest{" + "response=" + response + '}';
}
}
4 changes: 4 additions & 0 deletions src/main/java/org/redis2asp/protocol/request/GetRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,8 @@ public RedisResponse<byte[]> getResponse() {
return response;
}

@Override
public String toString() {
return "GetRequest{" + "key='" + key + '\'' + ", response=" + response + '}';
}
}
52 changes: 25 additions & 27 deletions src/main/java/org/redis2asp/protocol/request/SetRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,69 +17,62 @@
package org.redis2asp.protocol.request;

import java.nio.charset.StandardCharsets;
import java.util.List;
import org.redis2asp.protocol.RedisRequest;
import org.redis2asp.protocol.RedisResponse;
import org.redis2asp.protocol.response.BulkResponse;

public class SetRequest implements RedisRequest<byte[]> {

String key;
final String key;

String value;
final String value;

TtlType ttlType;

long ttl;
Long ttl;

Operate operate;

BulkResponse response = new BulkResponse();

public SetRequest(String key, String value) {
public SetRequest(String key, String value, List<String> params) {
this.key = key;
this.value = value;
if (params.contains("nx")) {
this.operate = Operate.NX;
} else if (params.contains("xx")) {
this.operate = Operate.XX;
}
if (params.contains("ex")) {
this.ttlType = TtlType.EX;
this.ttl = Long.parseLong(params.get(params.indexOf("ex") + 1));
} else if (params.contains("px")) {
this.ttlType = TtlType.PX;
this.ttl = Long.parseLong(params.get(params.indexOf("px") + 1));
}
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

public TtlType getTtlType() {
return ttlType;
}

public void setTtlType(String ttlType) {
this.ttlType = TtlType.valueOf(ttlType.toUpperCase());
}

public long getTtl() {
public Long getTtl() {
return ttl;
}

public void setTtl(long ttl) {
this.ttl = ttl;
}

public Operate getOperate() {
return operate;
}

public void setOperate(String operate) {
this.operate = Operate.valueOf(operate.toUpperCase());
}

@Override
public void setResponse(byte[] data) {
this.response.setData(data);
Expand All @@ -90,12 +83,17 @@ public RedisResponse<byte[]> getResponse() {
return response;
}

static enum TtlType {
public enum TtlType {
EX, PX
}

static enum Operate {
public enum Operate {
NX, XX
}

@Override
public String toString() {
return "SetRequest{" + "key='" + key + '\'' + ", value='" + value + '\'' + ", ttlType=" + ttlType + ", ttl="
+ ttl + ", operate=" + operate + ", response=" + response + '}';
}
}
16 changes: 16 additions & 0 deletions src/main/java/org/redis2asp/protocol/response/BulkResponse.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* 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 org.redis2asp.protocol.response;

import java.io.IOException;
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/org/redis2asp/protocol/response/IntegerResponse.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* 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 org.redis2asp.protocol.response;

import java.io.IOException;
Expand Down
40 changes: 40 additions & 0 deletions src/test/java/org/redis2asp/ServerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

public class ServerTest {
static Server server;
Expand Down Expand Up @@ -81,6 +82,45 @@ public void testGetNilAsp() {
}
}

@Test
public void testSetExAsp() {
String key = String.valueOf(ThreadLocalRandom.current().nextInt(50000));
try (Jedis jedis = new Jedis("127.0.0.1", 6789)) {
String result = jedis.set(key, "b", SetParams.setParams().ex(1L));
Assertions.assertEquals(result, "OK");
Thread.sleep(3000);
result = jedis.get(key);
Assertions.assertNull(result);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

@Test
public void testSetNxNilAsp() {
String key = String.valueOf(ThreadLocalRandom.current().nextInt(50000));
try (Jedis jedis = new Jedis("127.0.0.1", 6789)) {
String result = jedis.set(key, "b", SetParams.setParams().nx());
Assertions.assertEquals(result, "OK");
result = jedis.set(key, "b", SetParams.setParams().nx());
Assertions.assertNull(result);
}
}

@Test
public void testSetExNxAsp() {
String key = String.valueOf(ThreadLocalRandom.current().nextInt(50000));
try (Jedis jedis = new Jedis("127.0.0.1", 6789)) {
String result = jedis.set(key, "b", SetParams.setParams().nx().ex(1L));
Assertions.assertEquals(result, "OK");
Thread.sleep(3000);
result = jedis.get(key);
Assertions.assertNull(result);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

@AfterAll
public static void shutdown() {
Optional.ofNullable(server).ifPresent(Server::shutdown);
Expand Down
Loading