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

A few Redis usability improvements #32011

Merged
merged 1 commit into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ public int increment() {
return (int) commands.incrby("counter-dev-mode", INCREMENT);
}

@GET
@Path("/val")
public int value() {
return commands.get("counter-dev-mode");
}

@GET
@Path("/keys")
public int verifyPreloading() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import java.util.function.Function;
import java.util.function.Supplier;

import org.awaitility.Awaitility;
import org.hamcrest.Matchers;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

Expand Down Expand Up @@ -47,6 +49,10 @@ public String apply(String s) {
return s.replace("INCREMENT = 1", "INCREMENT = 10");
}
});

Awaitility.await()
.untilAsserted(() -> Assertions.assertEquals("2", RestAssured.get("/inc/val").andReturn().asString()));

RestAssured.get("/inc")
.then()
.statusCode(200)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@ public interface ReactiveTimeSeriesCommands<K> extends ReactiveRedisCommands {
**/
Uni<Void> tsAdd(K key, double value);

/**
* Execute the command <a href="https://redis.io/commands/ts.add/">TS.ADD</a>.
* Summary: Append a sample to a time series
* Group: time series
* <p>
* Unlike {@link #tsAdd(Object, long, double, AddArgs)}, set the timestamp according to the server clock.
*
* @param key the key name for the time series must not be {@code null}
* @param value the numeric data value of the sample.
* @param args the creation arguments.
* @return A uni emitting {@code null} when the operation completes
*/
Uni<Void> tsAdd(K key, double value, AddArgs args);

/**
* Execute the command <a href="https://redis.io/commands/ts.alter/">TS.ALTER</a>.
* Summary: Update the retention, chunk size, duplicate policy, and labels of an existing time series
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ public interface TimeSeriesCommands<K> extends RedisCommands {
*/
void tsAdd(K key, double value);

/**
* Execute the command <a href="https://redis.io/commands/ts.add/">TS.ADD</a>.
* Summary: Append a sample to a time series
* Group: time series
* <p>
* Unlike {@link #tsAdd(Object, long, double, AddArgs)}, set the timestamp according to the server clock.
*
* @param key the key name for the time series must not be {@code null}
* @param value the numeric data value of the sample.
* @param args the creation arguments.
*/
void tsAdd(K key, double value, AddArgs args);

/**
* Execute the command <a href="https://redis.io/commands/ts.alter/">TS.ALTER</a>.
* Summary: Update the retention, chunk size, duplicate policy, and labels of an existing time series
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ protected String getScoreAsString(double score) {

final List<ScoredValue<V>> decodeAsListOfScoredValues(Response response) {
List<ScoredValue<V>> list = new ArrayList<>();
if (!response.iterator().hasNext()) {
if (response == null || !response.iterator().hasNext()) {
return Collections.emptyList();
}
if (response.iterator().next().type() == ResponseType.BULK) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ Uni<Response> _tsAdd(K key, double value) {
return execute(cmd);
}

Uni<Response> _tsAdd(K key, double value, AddArgs args) {
nonNull(key, "key");
nonNull(args, "args");
RedisCommand cmd = RedisCommand.of(Command.TS_ADD).put(marshaller.encode(key)).put("*").put(value).putArgs(args);
return execute(cmd);
}

Uni<Response> _tsAlter(K key, AlterArgs args) {
nonNull(key, "key");
nonNull(args, "args");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public void tsAdd(K key, long timestamp, double value, AddArgs args) {
reactive.tsAdd(key, timestamp, value, args).await().atMost(timeout);
}

@Override
public void tsAdd(K key, double value, AddArgs args) {
reactive.tsAdd(key, value, args).await().atMost(timeout);
}

@Override
public void tsAdd(K key, long timestamp, double value) {
reactive.tsAdd(key, timestamp, value).await().atMost(timeout);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

import io.quarkus.redis.datasource.codecs.Codec;
Expand All @@ -25,13 +25,13 @@ public class Marshaller {
private static final Map<Class<?>, Codec<?>> DEFAULT_CODECS;

static {
DEFAULT_CODECS = new HashMap<>();
DEFAULT_CODECS.put(String.class, Codecs.StringCodec.INSTANCE);
DEFAULT_CODECS.put(Integer.class, Codecs.IntegerCodec.INSTANCE);
DEFAULT_CODECS.put(Double.class, Codecs.DoubleCodec.INSTANCE);
DEFAULT_CODECS = Map.of(
String.class, Codecs.StringCodec.INSTANCE,
Integer.class, Codecs.IntegerCodec.INSTANCE,
Double.class, Codecs.DoubleCodec.INSTANCE);
}

Map<Class<?>, Codec<?>> codecs = new HashMap<>();
Map<Class<?>, Codec<?>> codecs = new ConcurrentHashMap<>();

public Marshaller(Class<?>... hints) {
doesNotContainNull(hints, "hints");
Expand All @@ -51,11 +51,12 @@ public byte[] encode(Object o) {
}
Class<?> clazz = o.getClass();
Codec codec = codec(clazz);
if (codec != null) {
return codec.encode(o);
} else {
throw new IllegalArgumentException("Unable to encode object of type " + clazz);
if (codec == null) {
// Default to JSON.
codec = new Codecs.JsonCodec<>(clazz);
codecs.put(clazz, codec);
}
return codec.encode(o);
}

@SafeVarargs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ public Uni<Void> tsAdd(K key, long timestamp, double value, AddArgs args) {
.replaceWithVoid();
}

@Override
public Uni<Void> tsAdd(K key, double value, AddArgs args) {
return super._tsAdd(key, value, args)
.replaceWithVoid();
}

@Override
public Uni<Void> tsAdd(K key, long timestamp, double value) {
return super._tsAdd(key, timestamp, value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import io.quarkus.redis.datasource.list.KeyValue;
import io.quarkus.redis.datasource.list.LPosArgs;
import io.quarkus.redis.datasource.list.ListCommands;
Expand Down Expand Up @@ -352,4 +356,80 @@ void sort() {
assertThat(commands.lpop("dest2", 100)).containsExactly("1", "2", "3", "4", "5", "5", "6", "7", "8", "9");
}

@Test
void testJacksonPolymorphism() {
var cmd = ds.list(Animal.class);

var cat = new Cat();
cat.setId("1234");
cat.setName("the cat");

var rabbit = new Rabbit();
rabbit.setName("roxanne");
rabbit.setColor("grey");

cmd.lpush(key, cat, rabbit);

var shouldBeACat = cmd.rpop(key);
var shouldBeARabbit = cmd.rpop(key);

assertThat(shouldBeACat).isInstanceOf(Cat.class)
.satisfies(animal -> {
assertThat(animal.getName()).isEqualTo("the cat");
assertThat(((Cat) animal).getId()).isEqualTo("1234");
});

assertThat(shouldBeARabbit).isInstanceOf(Rabbit.class)
.satisfies(animal -> {
assertThat(animal.getName()).isEqualTo("roxanne");
assertThat(((Rabbit) animal).getColor()).isEqualTo("grey");
});
}

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),
@JsonSubTypes.Type(value = Rabbit.class, name = "Rabbit")
})
public static class Animal {

private String name;

public String getName() {
return name;
}

public Animal setName(String name) {
this.name = name;
return this;
}
}

public static class Rabbit extends Animal {

private String color;

public String getColor() {
return color;
}

public Rabbit setColor(String color) {
this.color = color;
return this;
}
}

public static class Cat extends Animal {
private String id;

public String getId() {
return id;
}

public Cat setId(String id) {
this.id = id;
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ void zrevrange() {
@RequiresRedis6OrHigher
void zrevrangeWithScoreEmpty() {
assertThat(ds.sortedSet(String.class).zrangeWithScores("top-products", 0, 2, new ZRangeArgs().rev())).isEmpty();
assertThat(ds.sortedSet(String.class).zrangeWithScores("missing", 0, 2)).isEmpty();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ void testCreationAndAddingDataPoint() throws InterruptedException {
assertThat(list).hasSize(1);
}

@Test
void testAdd() throws InterruptedException {
ts.tsAdd(key, 25.0);
Thread.sleep(10); // Make sure the timestamp is different
ts.tsAdd(key, 30.5, new AddArgs().label("foo", "bar"));
var list = ts.tsRange(key, TimeSeriesRange.fromTimeSeries());
assertThat(list).hasSize(2);
}

@Test
void testCreationWhileAdding() {
long timestamp = System.currentTimeMillis() - 1000;
Expand Down