Skip to content

Commit 9d4f4d5

Browse files
committed
Refactored JRedisTimeSeries out
Implemented custom command for TimeSeries in Lettuce.
1 parent ac73996 commit 9d4f4d5

File tree

8 files changed

+73
-43
lines changed

8 files changed

+73
-43
lines changed

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,23 @@ Via RedisCDC these changes will appear in demo application #1.
1010

1111
# Getting Started
1212

13+
## Running locally
14+
1315
1. Checkout the project
1416
2. `docker run -p 6379:6379 redislabs/redismod:latest`
1517
3. `./mvnw clean package spring-boot:run`
1618
4. Navigate to http://localhost:8080 and login with user lars and password larsje
17-
5. Watch in awe (or horror ;))
1819

19-
WIP
20+
## Running on Azure Spring Cloud
2021

21-
# Demo
22+
1. Follow the steps from 'Running locally'
23+
2. Make sure you are logged into the Azure CLI
24+
3. Add the Azure Spring Cloud extension to the Azure CLI `az extension add --name spring-cloud` If you already have the extension, make sure it's up to date using `az extension update --name spring-cloud`
25+
2. Create an Azure Spring Cloud instance using `az spring-cloud create -n acrebank -g rdsLroACRE -l northeurope` (this may take a few minutes)
26+
3. Create an App in the newly created Azure Spring Cloud instance using `az spring-cloud app create -n acrebankapp -s acrebank -g rdsLroACRE --assign-endpoint true`
27+
4. Modify the application.properties so it points to your newly created ACRE instance
28+
5. Rebuild the app using `./mvnw package`
29+
6. Deploy the app to Azure Spring Cloud using `az spring-cloud app deploy -n acrebankapp -s acrebank -g rdsLroAcre --jar-path target/redisbank-0.0.1-SNAPSHOT.jar`
2230

2331
Demo shows
2432

pom.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@
5151
<artifactId>spring-redisearch</artifactId>
5252
<version>3.1.2</version>
5353
</dependency>
54-
<dependency>
55-
<groupId>com.redislabs</groupId>
56-
<artifactId>jredistimeseries</artifactId>
57-
<version>1.4.0</version>
58-
</dependency>
5954
<dependency>
6055
<groupId>com.github.javafaker</groupId>
6156
<artifactId>javafaker</artifactId>
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.redislabs.demos.redisbank;
22

3-
import com.redislabs.redistimeseries.RedisTimeSeries;
4-
5-
import org.springframework.beans.factory.annotation.Value;
63
import org.springframework.context.annotation.Bean;
74
import org.springframework.context.annotation.Configuration;
85

6+
import io.lettuce.core.RedisClient;
7+
import io.lettuce.core.dynamic.RedisCommandFactory;
8+
99
@Configuration
1010
public class RedisTimeSeriesConfiguration {
1111

1212
@Bean
13-
RedisTimeSeries redisTimeSeries(@Value("${spring.redis.host}") String host, @Value("${spring.redis.port}") int port) {
14-
RedisTimeSeries rts = new RedisTimeSeries(host, port);
15-
return rts;
13+
RedisCommandFactory redisCommandFactory(RedisClient redis) {
14+
return new RedisCommandFactory(redis.connect());
1615
}
17-
16+
1817
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.redislabs.demos.redisbank.timeseries;
2+
3+
import java.util.Map;
4+
5+
import io.lettuce.core.dynamic.Commands;
6+
import io.lettuce.core.dynamic.annotation.Command;
7+
8+
public interface TimeSeriesCommands extends Commands {
9+
10+
@Command("TS.CREATE :key RETENTION :retentionTime ")
11+
void create(String key, long retentionTime);
12+
13+
@Command("TS.ADD :key * :value")
14+
void add(String key, double value);
15+
16+
@Command("TS.RANGE :key :from :to")
17+
Map<String, String> range(String key, long from, long to);
18+
19+
}
Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
package com.redislabs.demos.redisbank.transactions;
22

3-
import com.redislabs.redistimeseries.Value;
4-
53
import lombok.AllArgsConstructor;
64
import lombok.Data;
75

86
@Data
97
@AllArgsConstructor
108
public class Balance {
119

12-
private long x;
13-
private double y;
14-
15-
public Balance(Value v) {
16-
this.x = v.getTime();
17-
this.y = v.getValue();
18-
}
10+
private Object x;
11+
private Object y;
1912

2013
}

src/main/java/com/redislabs/demos/redisbank/transactions/BankTransactionGenerator.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
import com.fasterxml.jackson.core.JsonProcessingException;
1515
import com.redislabs.demos.redisbank.SerializationUtil;
1616
import com.redislabs.demos.redisbank.Utilities;
17+
import com.redislabs.demos.redisbank.timeseries.TimeSeriesCommands;
1718
import com.redislabs.lettusearch.Field;
1819
import com.redislabs.lettusearch.Field.Text.PhoneticMatcher;
1920
import com.redislabs.lettusearch.RediSearchCommands;
2021
import com.redislabs.lettusearch.StatefulRediSearchConnection;
21-
import com.redislabs.redistimeseries.RedisTimeSeries;
2222

2323
import org.slf4j.Logger;
2424
import org.slf4j.LoggerFactory;
@@ -27,6 +27,7 @@
2727
import org.springframework.stereotype.Component;
2828

2929
import io.lettuce.core.RedisCommandExecutionException;
30+
import io.lettuce.core.dynamic.RedisCommandFactory;
3031

3132
@Component
3233
public class BankTransactionGenerator {
@@ -47,13 +48,13 @@ public class BankTransactionGenerator {
4748

4849
private final StringRedisTemplate redis;
4950
private final StatefulRediSearchConnection<String, String> connection;
50-
private final RedisTimeSeries rts;
51+
private final TimeSeriesCommands tsc;
5152

5253
public BankTransactionGenerator(StringRedisTemplate redis, StatefulRediSearchConnection<String, String> connection,
53-
RedisTimeSeries rts) throws NoSuchAlgorithmException, UnsupportedEncodingException {
54+
RedisCommandFactory rcf) throws NoSuchAlgorithmException, UnsupportedEncodingException {
5455
this.redis = redis;
5556
this.connection = connection;
56-
this.rts = rts;
57+
this.tsc = rcf.getCommands(TimeSeriesCommands.class);
5758
transactionSources = SerializationUtil.loadObjectList(TransactionSource.class, "transaction_sources.csv");
5859
random = SecureRandom.getInstance("SHA1PRNG");
5960
random.setSeed("lars".getBytes("UTF-8")); // Prime the RNG so it always generates the same pseudorandom set
@@ -86,13 +87,13 @@ private void createSearchIndices() {
8687
Field.text("transactionType").matcher(PhoneticMatcher.English).build());
8788
}
8889

89-
private void deleteSortedSet() {
90+
private void deleteSortedSet() {
9091
redis.delete(SORTED_SET_KEY);
9192
}
9293

9394
private void createTimeSeries() {
9495
redis.delete(BALANCE_TS);
95-
rts.create(BALANCE_TS, 0, null);
96+
tsc.create(BALANCE_TS, 0);
9697
}
9798

9899
private void createInitialStream() {
@@ -143,12 +144,12 @@ private String createTransactionAmount(String accountName) {
143144
Double amount = random.nextDouble() * bandwidth % 300.0;
144145
Double roundedAmount = Math.floor(amount * 100) / 100;
145146

146-
if (random.nextBoolean()) {
147+
if (random.nextBoolean()) {
147148
roundedAmount = roundedAmount * -1.00;
148149
}
149150

150151
balance = balance + roundedAmount;
151-
rts.add(BALANCE_TS, balance);
152+
tsc.add(BALANCE_TS, balance);
152153
redis.opsForZSet().incrementScore(SORTED_SET_KEY, accountName, roundedAmount * -1);
153154

154155
return nf.format(roundedAmount);

src/main/java/com/redislabs/demos/redisbank/transactions/TransactionOverviewController.java

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
package com.redislabs.demos.redisbank.transactions;
22

3+
import java.util.Map;
4+
import java.util.Map.Entry;
35
import java.util.Set;
46

57
import com.redislabs.demos.redisbank.Config;
68
import com.redislabs.demos.redisbank.Config.StompConfig;
79
import com.redislabs.demos.redisbank.UserSession;
810
import com.redislabs.demos.redisbank.UserSessionRepository;
911
import com.redislabs.demos.redisbank.Utilities;
12+
import com.redislabs.demos.redisbank.timeseries.TimeSeriesCommands;
1013
import com.redislabs.lettusearch.RediSearchCommands;
1114
import com.redislabs.lettusearch.SearchOptions;
1215
import com.redislabs.lettusearch.SearchOptions.Highlight;
1316
import com.redislabs.lettusearch.SearchOptions.Highlight.Tag;
1417
import com.redislabs.lettusearch.SearchResults;
1518
import com.redislabs.lettusearch.StatefulRediSearchConnection;
16-
import com.redislabs.redistimeseries.RedisTimeSeries;
17-
import com.redislabs.redistimeseries.Value;
1819

20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
1922
import org.springframework.data.redis.core.StringRedisTemplate;
2023
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
2124
import org.springframework.web.bind.annotation.CrossOrigin;
@@ -24,11 +27,15 @@
2427
import org.springframework.web.bind.annotation.RequestParam;
2528
import org.springframework.web.bind.annotation.RestController;
2629

30+
import io.lettuce.core.dynamic.RedisCommandFactory;
31+
2732
@RestController
2833
@RequestMapping(path = "/api")
2934
@CrossOrigin
3035
public class TransactionOverviewController {
3136

37+
private static final Logger LOGGER = LoggerFactory.getLogger(TransactionOverviewController.class);
38+
3239
private static final String ACCOUNT_INDEX = "transaction_account_idx";
3340
private static final String SEARCH_INDEX = "transaction_description_idx";
3441
private static final String BALANCE_TS = "balance_ts";
@@ -37,15 +44,15 @@ public class TransactionOverviewController {
3744
private final Config config;
3845
private final UserSessionRepository userSessionRepository;
3946
private final StatefulRediSearchConnection<String, String> srsc;
40-
private final RedisTimeSeries rts;
4147
private final StringRedisTemplate redis;
48+
private final TimeSeriesCommands tsc;
4249

4350
public TransactionOverviewController(Config config, UserSessionRepository userSessionRepository,
44-
StatefulRediSearchConnection<String, String> srsc, RedisTimeSeries rts, StringRedisTemplate redis) {
51+
StatefulRediSearchConnection<String, String> srsc, RedisCommandFactory rcf, StringRedisTemplate redis) {
4552
this.config = config;
4653
this.userSessionRepository = userSessionRepository;
4754
this.srsc = srsc;
48-
this.rts = rts;
55+
this.tsc = rcf.getCommands(TimeSeriesCommands.class);
4956
this.redis = redis;
5057
}
5158

@@ -55,14 +62,18 @@ public StompConfig stompConfig() {
5562
}
5663

5764
@GetMapping("/balance")
58-
public Balance[] listTransactionsByDate() {
59-
Value[] tsValues = rts.range(BALANCE_TS, System.currentTimeMillis() - (1000 * 60 * 60 * 24 * 7),
65+
public Balance[] balance() {
66+
Map<String, String> tsValues = tsc.range(BALANCE_TS, System.currentTimeMillis() - (1000 * 60 * 60 * 24 * 7),
6067
System.currentTimeMillis());
6168

62-
Balance[] balanceTs = new Balance[tsValues.length];
69+
Balance[] balanceTs = new Balance[tsValues.size()];
70+
int i = 0;
6371

64-
for (int i = 0; i < tsValues.length; i++) {
65-
balanceTs[i] = new Balance(tsValues[i]);
72+
for (Entry<String, String> entry : tsValues.entrySet()) {
73+
Object keyString = entry.getKey();
74+
Object valueString = entry.getValue();
75+
balanceTs[i] = new Balance(keyString, valueString);
76+
i++;
6677
}
6778

6879
return balanceTs;

src/main/resources/application.properties

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ stomp.destinationPrefix=/topic
66
stomp.transactionsTopic=/topic/transactions
77

88
spring.redis.host=localhost
9-
spring.redis.port=6379
9+
spring.redis.port=6379
10+
11+
#spring.redis.host=lars5.northeurope.redisenterprise.cache.azure.net
12+
#spring.redis.port=10000
13+
#spring.redis.password=RzM8a9+p2VHu6ZWVwKWyHbHZBUc1jueNWLg8uQZPe9w=

0 commit comments

Comments
 (0)