Skip to content

Commit fd148e8

Browse files
authored
Merge pull request #30 from picoded/redis-support
WIP Redis support
2 parents 284a2ae + e168437 commit fd148e8

11 files changed

Lines changed: 1011 additions & 6 deletions

File tree

.github/workflows/redis.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Redis support test
2+
on:
3+
push:
4+
branches: [ master, "redis*", "*redis*" ]
5+
pull_request:
6+
branches: [ master ]
7+
jobs:
8+
unit_test:
9+
runs-on: ubuntu-latest
10+
11+
# Configuration, for us to perform test against multiple version in the future
12+
strategy:
13+
matrix:
14+
redis-version: [7]
15+
16+
# The test step
17+
steps:
18+
# Start Redis
19+
- name: Start Redis
20+
uses: supercharge/redis-github-action@1.4.0
21+
with:
22+
redis-version: ${{ matrix.redis-version }}
23+
24+
# The usual checkout, and test
25+
- uses: actions/checkout@v1
26+
- name: Init submodules
27+
run: ./git-init-submodules.sh
28+
- name: Set up JDK 1.8
29+
uses: actions/setup-java@v1
30+
with:
31+
java-version: 1.8
32+
- name: Cache Gradle packages
33+
uses: actions/cache@v2
34+
with:
35+
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/build.gradle') }}
36+
path: |
37+
~/.gradle/caches
38+
~/.gradle/wrapper
39+
- name: Setup gradle binaries
40+
run: ./gradlew
41+
- name: Pull dependencies libs, and perform initial compile
42+
run: ./gradlew src
43+
- name: Run unit tests
44+
run: ./gradlew test -Ptest_redis
45+
- name: Run jacocoTestReport
46+
run: ./gradlew jacocoTestReport
47+
- name: Archive code coverage results
48+
uses: actions/upload-artifact@v2
49+
if: always()
50+
with:
51+
name: test-result-report
52+
path: |
53+
build/reports/**/*
54+
build/test-results/**/*
55+
build/jacoco/**/*
56+
- name: Upload code coverage to codecov
57+
uses: codecov/codecov-action@v2
58+
if: always()
59+
with:
60+
# flags: gradle-build # optional
61+
# directory: build/jacoco/
62+
verbose: true # optional (default = false)
63+
fail_ci_if_error: false

build.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ dependencies {
113113
api 'org.mongodb:mongodb-driver-sync:4.5.1'
114114
api 'com.github.luben:zstd-jni:1.5.2-3'
115115

116+
// Redis
117+
api 'org.redisson:redisson:3.17.1'
118+
116119
// PostgresSQL library
117120
api "org.postgresql:postgresql:42.2.5"
118121

@@ -279,6 +282,9 @@ test {
279282
if(!project.hasProperty("test_mongodb")) {
280283
exclude "**/*MongoDB*"
281284
}
285+
if(!project.hasProperty("test_redis")) {
286+
exclude "**/*Redis*"
287+
}
282288
}
283289

284290
// Setup test to run on parllel threads = to number of processors by default
@@ -382,6 +388,9 @@ task incrementalTest(type: TestWatcher) {
382388
if(!project.hasProperty("test_mongodb")) {
383389
exclude "**/*MongoDB*"
384390
}
391+
if(!project.hasProperty("test_redis")) {
392+
exclude "**/*Redis*"
393+
}
385394
}
386395

387396
// Setup test to run on parllel threads = to number of processors by default

src/main/java/picoded/dstack/DataObjectMap.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,19 +324,19 @@ default String[] getFromKeyName_id(String keyName, String orderByStr, int offset
324324
**/
325325
@Override
326326
default int size() {
327-
long s = queryCount(null,null);
328-
if( s > Integer.MAX_VALUE ) {
327+
long s = queryCount(null, null);
328+
if (s > Integer.MAX_VALUE) {
329329
return Integer.MAX_VALUE;
330-
}
331-
return (int)s;
330+
}
331+
return (int) s;
332332
}
333-
333+
334334
/**
335335
* Get the size as a long for the DataObjectMap
336336
* This should be used instead of size (to work around int limits)
337337
*/
338338
default long longSize() {
339-
return queryCount(null,null);
339+
return queryCount(null, null);
340340
}
341341

342342
//
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package picoded.dstack.redisson;
2+
3+
import java.util.Map;
4+
import java.util.logging.Level;
5+
import java.util.logging.Logger;
6+
7+
import picoded.core.struct.GenericConvertMap;
8+
import picoded.dstack.core.*;
9+
10+
import org.redisson.Redisson;
11+
import org.redisson.config.Config;
12+
import org.redisson.api.RedissonClient;
13+
14+
/**
15+
* [Internal use only]
16+
*
17+
* Redisson based stack provider
18+
**/
19+
public class RedissonStack extends CoreStack {
20+
21+
/**
22+
* The internal Redis connection
23+
*/
24+
25+
protected RedissonClient conn = null;
26+
27+
//-------------------------------------------------------------------------
28+
// Database connection constructor
29+
//-------------------------------------------------------------------------
30+
31+
/**
32+
* Given the redis config object, get the full_url
33+
* https://github.com/lettuce-io/lettuce-core/wiki/Redis-URI-and-connection-details
34+
*/
35+
public static String getFullConnectionURL(GenericConvertMap<String, Object> config) {
36+
37+
// Get the full connection url, and use it if present
38+
String full_url = config.getString("full_url", null);
39+
if (full_url != null) {
40+
return full_url;
41+
}
42+
43+
// Get the DB name (required)
44+
// Redis db are labelled from 0 to 15
45+
String dbname = config.getString("name", null);
46+
if (dbname == null || dbname.isEmpty()) {
47+
throw new IllegalArgumentException("Missing database 'name' for redis config");
48+
}
49+
50+
// Lets get the config respectively
51+
String protocol = config.getString("protocol", "redis");
52+
String user = config.getString("user", null);
53+
String pass = config.getString("pass", null);
54+
String host = config.getString("host", "172.17.0.1"); //default docker ip
55+
int port = config.getInt("port", 6379); //default redis port
56+
57+
// Lets build the auth str
58+
String authStr = "";
59+
if (user != null && pass != null) {
60+
authStr = user + ":" + pass + "@";
61+
}
62+
63+
return protocol + "://" + authStr + host + ":" + port + "/" + dbname;
64+
}
65+
66+
/**
67+
* Given the redis config object, get the Redisson client connection
68+
*/
69+
public static RedissonClient setupFromConfig(GenericConvertMap<String, Object> inConfig) {
70+
// Get the full_url
71+
String full_url = getFullConnectionURL(inConfig);
72+
73+
// Apply config
74+
Config config = new Config();
75+
config.useSingleServer().setAddress(full_url);
76+
77+
// Create the client, and return it
78+
return Redisson.create(config);
79+
}
80+
81+
/**
82+
* Constructor with configuration map
83+
*/
84+
public RedissonStack(GenericConvertMap<String, Object> inConfig) {
85+
//https://github.com/redisson/redisson/wiki/10.-additional-features#107-low-level-redis-client
86+
super(inConfig);
87+
88+
// Extract the connection config object
89+
GenericConvertMap<String, Object> dbConfig = inConfig.fetchGenericConvertStringMap("redis");
90+
91+
// If DB config is missing, throw an error
92+
if (dbConfig == null) {
93+
throw new IllegalArgumentException(
94+
"Missing 'RedissonStack' config object for Redis stack provider");
95+
}
96+
97+
// Get the connection & database
98+
conn = setupFromConfig(dbConfig);
99+
}
100+
101+
//--------------------------------------------------------------------------
102+
//
103+
// Internal package methods
104+
//
105+
//--------------------------------------------------------------------------
106+
107+
// /**
108+
// * @return pong
109+
// */
110+
// protected String ping() {
111+
// return "pong";
112+
// }
113+
114+
/**
115+
* @return the internal hazelcastInstance connection
116+
*/
117+
protected RedissonClient getConnection() {
118+
return conn;
119+
}
120+
121+
/**
122+
* Initialize and return the requested data structure with the given name or type if its supported
123+
*
124+
* @param name name of the datastructure to initialize
125+
* @param type implmentation type (KeyValueMap / KeyLongMap / DataObjectMap / FileWorkspaceMap)
126+
*
127+
* @return initialized data structure if type is supported
128+
*/
129+
protected Core_DataStructure initDataStructure(String name, String type) {
130+
// Initialize for the respective type
131+
Core_DataStructure ret = null;
132+
if (type.equalsIgnoreCase("DataObjectMap")) {
133+
ret = new Redisson_DataObjectMap(this, name);
134+
}
135+
if (type.equalsIgnoreCase("KeyValueMap")) {
136+
ret = new Redisson_KeyValueMap(this, name);
137+
}
138+
// If datastrucutre initialized, setup name
139+
if (ret != null) {
140+
ret.configMap().put("name", name);
141+
}
142+
// Return the initialized object (or null)
143+
return ret;
144+
}
145+
}

0 commit comments

Comments
 (0)