Skip to content

Commit 2bc38d2

Browse files
authored
Redis connection did not support custom port (#565)
* Redis connection not supporting some urls. Added UnitTesting * Prepare for Guthub action testing * Add CI Testing * Rename test * Only redis 6 * CI redis * Change ci order * Minor improvements * Do not check connection on Redis Startup to keep compatibility * Fix Log Output
1 parent 8a50df2 commit 2bc38d2

File tree

3 files changed

+234
-111
lines changed

3 files changed

+234
-111
lines changed

.github/workflows/RedisTests.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Redis Cache Tests
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
branches:
7+
- 'master'
8+
- 'release-*'
9+
push:
10+
branches:
11+
- 'master'
12+
- 'beta'
13+
- 'release-*'
14+
15+
jobs:
16+
test-redis:
17+
name: Test Redis Cache
18+
env:
19+
GIT_REF: ${{ github.ref }}
20+
GIT_SHA: ${{ github.sha }}
21+
POM_PATH: ./pom.xml
22+
23+
runs-on: ubuntu-latest
24+
strategy:
25+
matrix:
26+
redis-version: [ 6 ]
27+
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@v2
31+
with:
32+
fetch-depth: 1
33+
34+
- name: Setup Java JDK
35+
uses: actions/setup-java@v1.4.3
36+
with:
37+
java-version: 1.9
38+
39+
- name: Setup Maven settings
40+
uses: whelk-io/maven-settings-xml-action@v14
41+
with:
42+
repositories: '[{ "id": "github-genexuslabs", "url": "https://maven.pkg.github.com/genexuslabs/Private-Maven-for-GX", "releases": { "enabled": "true" }, "snapshots": { "enabled": "true" } }]'
43+
servers: '[{ "id": "github-genexuslabs", "username": "genexusbot", "password": "${{ secrets.SECURE_TOKEN }}" }]'
44+
45+
- name: Install
46+
run: mvn -B install --file $POM_PATH
47+
48+
- name: Start Redis
49+
uses: supercharge/redis-github-action@1.4.0
50+
with:
51+
redis-version: ${{ matrix.redis-version }}
52+
53+
- name: Test Redis
54+
run: |
55+
export EXECUTE_REDIS_TESTS=true
56+
mvn -B -pl java test --file $POM_PATH

java/src/main/java/com/genexus/cache/redis/RedisClient.java

Lines changed: 68 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.Closeable;
44
import java.io.IOException;
55
import java.net.URI;
6+
import java.net.URISyntaxException;
67
import java.util.ArrayList;
78
import java.util.List;
89

@@ -26,105 +27,96 @@
2627
import redis.clients.jedis.Pipeline;
2728

2829

29-
public class RedisClient implements ICacheService2, Closeable{
30+
public class RedisClient implements ICacheService2, Closeable {
3031
public static final ILogger logger = LogManager.getLogger(RedisClient.class);
3132
private String keyPattern = "%s_%s_%s"; //Namespace_KEY
32-
private static int UNDEFINED_PORT = -1;
3333
private static int REDIS_DEFAULT_PORT = 6379;
3434
private JedisPool pool;
35-
private ObjectMapper objMapper;
36-
public RedisClient() throws IOException {
35+
private ObjectMapper objMapper;
36+
37+
public RedisClient() throws URISyntaxException {
3738
initCache();
3839
}
3940

40-
private void initCache() throws IOException {
41-
objMapper = new ObjectMapper();
42-
objMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
43-
objMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
44-
objMapper.enable(SerializationFeature.INDENT_OUTPUT);
41+
public RedisClient(String hostOrRedisURL, String password, String cacheKeyPattern) throws URISyntaxException {
42+
initCache(hostOrRedisURL, password, cacheKeyPattern);
43+
}
4544

45+
public JedisPool getConnection() {
46+
return pool;
47+
}
48+
49+
private void initCache() throws URISyntaxException {
4650
GXService providerService = Application.getGXServices().get(GXServices.CACHE_SERVICE);
4751
String addresses = providerService.getProperties().get("CACHE_PROVIDER_ADDRESS");
4852
String cacheKeyPattern = providerService.getProperties().get("CACHE_PROVIDER_KEYPATTERN");
4953
String password = providerService.getProperties().get("CACHE_PROVIDER_PASSWORD");
54+
initCache(addresses, password, cacheKeyPattern);
55+
}
5056

51-
if (!isNullOrEmpty(cacheKeyPattern))
52-
keyPattern = cacheKeyPattern;
53-
54-
if (!isNullOrEmpty(addresses)){
57+
private void initCache(String hostOrRedisURL, String password, String cacheKeyPattern) throws URISyntaxException {
58+
keyPattern = isNullOrEmpty(cacheKeyPattern) ? keyPattern : cacheKeyPattern;
59+
String host = "127.0.0.1";
60+
hostOrRedisURL = isNullOrEmpty(hostOrRedisURL) ? host: hostOrRedisURL;
61+
int port = REDIS_DEFAULT_PORT;
5562

56-
if (!isNullOrEmpty(password)) {
63+
boolean isRedisURIScheme = hostOrRedisURL.startsWith("redis://");
64+
String sRedisURI = isRedisURIScheme ? hostOrRedisURL : "redis://" + hostOrRedisURL;
5765

58-
addresses = "redis://:" + password.trim() + "@" + addresses.trim();
59-
try {
60-
URI redisUri = new URI(addresses);
61-
if (redisUri.getPort()==UNDEFINED_PORT){
62-
redisUri = new URI(addresses + ":" + REDIS_DEFAULT_PORT);
63-
}
64-
pool = new JedisPool(new JedisPoolConfig(), redisUri);
65-
}catch (java.net.URISyntaxException ex){
66-
logger.error("Invalid redis uri " + addresses, ex);
67-
}
66+
try {
67+
URI redisURI = new URI(sRedisURI);
68+
host = redisURI.getHost();
69+
if (redisURI.getPort() > 0) {
70+
port = redisURI.getPort();
6871
}
69-
}else{
70-
addresses ="127.0.0.1:" + REDIS_DEFAULT_PORT;
72+
} catch (URISyntaxException e) {
73+
logger.error(String.format("Could not parse Redis URL. Check for supported URLs: %s" , sRedisURI), e);
74+
throw e;
7175
}
72-
if (pool == null)
73-
pool = new JedisPool(new JedisPoolConfig(), addresses);
76+
77+
password = (!isNullOrEmpty(password)) ? password : null;
78+
79+
pool = new JedisPool(new JedisPoolConfig(), host, port, redis.clients.jedis.Protocol.DEFAULT_TIMEOUT, password);
80+
81+
objMapper = new ObjectMapper();
82+
objMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
83+
objMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
84+
objMapper.enable(SerializationFeature.INDENT_OUTPUT);
7485
}
75-
86+
7687
private boolean isNullOrEmpty(String s) {
7788
return s == null || s.trim().length() == 0;
7889
}
7990

8091
private Boolean containsKey(String key) {
81-
Jedis jedis = null;
82-
try {
83-
jedis = pool.getResource();
92+
try (Jedis jedis = pool.getResource()) {
8493
return jedis.exists(key);
8594
} catch (Exception e) {
8695
logger.error("Contains failed", e);
8796
}
88-
finally {
89-
close(jedis);
90-
}
9197
return false;
9298
}
9399

94-
private void close(Jedis jedis) {
95-
if (jedis != null)
96-
{
97-
jedis.close();
98-
}
99-
}
100-
101100
private <T> void set(String key, T value) {
102101
set(key, value, 0);
103102
}
104103

105104
private <T> void set(String key, T value, int expirationSeconds) {
106-
Jedis jedis = null;
107-
try {
108-
jedis = pool.getResource();
105+
try (Jedis jedis = pool.getResource()) {
109106
String valueJSON = objMapper.writeValueAsString(value);
110107
if (expirationSeconds > 0)
111108
jedis.setex(key, expirationSeconds, valueJSON);
112109
else
113110
jedis.set(key, valueJSON);
114111
} catch (Exception e) {
115112
logger.error("Set with TTL failed", e);
116-
}
117-
finally {
118-
close(jedis);
119113
}
120114
}
121115

122116
public <T> void setAll(String cacheid, String[] keys, T[] values, int expirationSeconds) {
123-
Jedis jedis = null;
124-
try {
125-
if (keys!=null && values!=null && keys.length == values.length) {
117+
try (Jedis jedis = pool.getResource()) {
118+
if (keys != null && values != null && keys.length == values.length) {
126119
String[] prefixedKeys = getKey(cacheid, keys);
127-
jedis = pool.getResource();
128120
Pipeline p = jedis.pipelined();
129121
int idx = 0;
130122
for (String key : prefixedKeys) {
@@ -140,56 +132,41 @@ public <T> void setAll(String cacheid, String[] keys, T[] values, int expiration
140132
} catch (Exception e) {
141133
logger.error("SetAll with TTL failed", e);
142134
}
143-
finally {
144-
close(jedis);
145-
}
146135
}
147136

148137
private <T> T get(String key, Class<T> type) {
149-
Jedis jedis = null;
150-
try {
151-
jedis = pool.getResource();
138+
try (Jedis jedis = pool.getResource()) {
152139
String json = jedis.get(key);
153-
if (StringUtils.isNotEmpty(json))
154-
{
155-
return objMapper.readValue(json, type);
156-
}
157-
else
158-
{
140+
if (StringUtils.isNotEmpty(json)) {
141+
return objMapper.readValue(json, type);
142+
} else {
159143
return null;
160144
}
161145
} catch (Exception e) {
162146
logger.error("Get Item failed", e);
163147
}
164-
finally {
165-
close(jedis);
166-
}
167148
return null;
168149
}
169-
public <T> List<T> getAll(String cacheid, String[] keys, Class<T> type){
150+
151+
public <T> List<T> getAll(String cacheid, String[] keys, Class<T> type) {
170152
List<T> result = null;
171-
Jedis jedis = null;
172-
try {
153+
try (Jedis jedis = pool.getResource()) {
173154
String[] prefixedKeys = getKey(cacheid, keys);
174-
jedis = pool.getResource();
175155
List<String> json = jedis.mget(prefixedKeys);
176156
result = new ArrayList<T>();
177-
for (String val: json) {
157+
for (String val : json) {
178158
if (val != null)
179-
result.add(objMapper.readValue(val, type));
159+
result.add(objMapper.readValue(val, type));
180160
else
181161
result.add(null);
182162
}
183163
return result;
184164
} catch (Exception e) {
185165
logger.error("Get Item failed", e);
186166
}
187-
finally {
188-
close(jedis);
189-
}
190167
return null;
191168
}
192-
169+
193170

194171
public boolean containtsKey(String cacheid, String key) {
195172
return containsKey(getKey(cacheid, key));
@@ -198,7 +175,7 @@ public boolean containtsKey(String cacheid, String key) {
198175
public <T> T get(String cacheid, String key, Class<T> type) {
199176
return get(getKey(cacheid, key), type);
200177
}
201-
178+
202179

203180
public <T> void set(String cacheid, String key, T value) {
204181
set(getKey(cacheid, key), value);
@@ -209,72 +186,51 @@ public <T> void set(String cacheid, String key, T value, int duration) {
209186
}
210187

211188
public void clear(String cacheid, String key) {
212-
Jedis jedis = null;
213-
try {
214-
jedis = pool.getResource();
189+
try (Jedis jedis = pool.getResource()) {
215190
jedis.del(getKey(cacheid, key));
216191
} catch (Exception e) {
217192
logger.error("Remove Item failed", e);
218193
}
219-
finally {
220-
close(jedis);
221-
}
222194
}
223195

224196
public void clearCache(String cacheid) {
225-
Jedis jedis = null;
226-
try {
227-
jedis = pool.getResource();
228-
jedis.incr(cacheid);
197+
try (Jedis jedis = pool.getResource()) {
198+
jedis.incr(cacheid);
229199
} catch (Exception e) {
230200
logger.error("clearCache failed", e);
231201
}
232-
finally {
233-
close(jedis);
234-
}
235202
}
236203

237204
public void clearKey(String key) {
238-
Jedis jedis = null;
239-
try {
240-
jedis = pool.getResource();
241-
jedis.del(key);
205+
try (Jedis jedis = pool.getResource()) {
206+
jedis.del(key);
242207
} catch (Exception e) {
243208
logger.error("Remove Item failed", e);
244209
}
245-
finally {
246-
close(jedis);
247-
}
248210
}
249211

250212
public void clearAllCaches() {
251-
Jedis jedis = null;
252-
try {
253-
jedis = pool.getResource();
254-
jedis.flushAll();
213+
try (Jedis jedis = pool.getResource()) {
214+
jedis.flushAll();
255215
} catch (Exception e) {
256216
logger.error("Clear All Caches failed", e);
257217
}
258-
finally {
259-
close(jedis);
260-
}
261218
}
262219

263220
private String getKey(String cacheid, String key) {
264221
return String.format(keyPattern, cacheid, getKeyPrefix(cacheid), com.genexus.CommonUtil.getHash(key));
265222
}
266223

267-
private String[] getKey(String cacheid, String[] keys)
268-
{
224+
private String[] getKey(String cacheid, String[] keys) {
269225
Long prefix = getKeyPrefix(cacheid);
270226
String[] prefixedKeys = new String[keys.length];
271-
for (int idx =0; idx<keys.length; idx++){
227+
for (int idx = 0; idx < keys.length; idx++) {
272228
prefixedKeys[idx] = formatKey(cacheid, keys[idx], prefix);
273229
}
274230
return prefixedKeys;
275231
}
276-
private String formatKey(String cacheid, String key, Long prefix)
277-
{
232+
233+
private String formatKey(String cacheid, String key, Long prefix) {
278234
return String.format(keyPattern, cacheid, prefix, com.genexus.CommonUtil.getHash(key));
279235
}
280236

@@ -286,8 +242,9 @@ private Long getKeyPrefix(String cacheid) {
286242
}
287243
return prefix;
288244
}
245+
289246
@Override
290-
public void close() throws IOException {
247+
public void close() throws IOException {
291248
if (pool != null)
292249
pool.destroy();
293250
}

0 commit comments

Comments
 (0)