From 09ffbe8069d2e84273eecf69b804b3b0454afc51 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Fri, 27 May 2022 14:46:25 -0300 Subject: [PATCH 1/7] try fix redis serialization error --- .../com/genexus/cache/redis/RedisClient.java | 1 + .../cache/redis/TestRedisCacheClient.java | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/java/src/main/java/com/genexus/cache/redis/RedisClient.java b/java/src/main/java/com/genexus/cache/redis/RedisClient.java index 003871ca7..f8abe4d48 100644 --- a/java/src/main/java/com/genexus/cache/redis/RedisClient.java +++ b/java/src/main/java/com/genexus/cache/redis/RedisClient.java @@ -81,6 +81,7 @@ private void initCache(String hostOrRedisURL, String password, String cacheKeyPa objMapper = new ObjectMapper(); objMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); objMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + objMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); objMapper.enable(SerializationFeature.INDENT_OUTPUT); } diff --git a/java/src/test/java/com/genexus/cache/redis/TestRedisCacheClient.java b/java/src/test/java/com/genexus/cache/redis/TestRedisCacheClient.java index 856886e59..67640fa1d 100644 --- a/java/src/test/java/com/genexus/cache/redis/TestRedisCacheClient.java +++ b/java/src/test/java/com/genexus/cache/redis/TestRedisCacheClient.java @@ -1,5 +1,6 @@ package com.genexus.cache.redis; +import com.genexus.db.CacheValue; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.genexus.specific.java.Connect; @@ -100,11 +101,25 @@ public void testSetRedis() redis.set(cacheId, cacheKey, cacheValue); String obtainedValue = redis.get(cacheId, cacheKey, String.class); - Assert.assertEquals(obtainedValue, cacheValue); + } + @Test + public void testSetCacheValueRedis() + { + Connect.init(); + RedisClient redis = getRedisClient("", ""); + Assert.assertNotNull("Redis instance could not be created", redis); + String cacheId = "TEST"; + String cacheKey = "TEST_KEY"; + CacheValue c = new CacheValue("SELECT * FROM User;", new Object[] { 1, 2, 3}); + c.addItem(123); + redis.set(cacheId, cacheKey, c); + CacheValue obtainedValue = redis.get(cacheId, cacheKey, CacheValue.class); + Assert.assertNotNull(obtainedValue); } + } From 5d16ff03d45e62de935077387f16a22375861ce7 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Fri, 27 May 2022 15:07:52 -0300 Subject: [PATCH 2/7] no message --- java/src/main/java/com/genexus/db/CacheValue.java | 7 +++++-- .../java/com/genexus/cache/redis/TestRedisCacheClient.java | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/java/src/main/java/com/genexus/db/CacheValue.java b/java/src/main/java/com/genexus/db/CacheValue.java index fd3d89e90..0f7106996 100644 --- a/java/src/main/java/com/genexus/db/CacheValue.java +++ b/java/src/main/java/com/genexus/db/CacheValue.java @@ -1,4 +1,6 @@ package com.genexus.db; +import com.fasterxml.jackson.annotation.JsonIgnore; + import java.io.Serializable; import java.util.Enumeration; import java.util.TimeZone; @@ -173,8 +175,9 @@ public void setTimestamp() public long getTimestamp() { return timestamp; - } - //IFieldGetter iterator + } + + @JsonIgnore public Enumeration getIterator() { return items.elements(); diff --git a/java/src/test/java/com/genexus/cache/redis/TestRedisCacheClient.java b/java/src/test/java/com/genexus/cache/redis/TestRedisCacheClient.java index 67640fa1d..f20d7258d 100644 --- a/java/src/test/java/com/genexus/cache/redis/TestRedisCacheClient.java +++ b/java/src/test/java/com/genexus/cache/redis/TestRedisCacheClient.java @@ -11,6 +11,7 @@ import redis.clients.jedis.JedisPool; import java.net.URISyntaxException; +import java.util.concurrent.ThreadLocalRandom; import static org.junit.Assume.assumeTrue; @@ -96,7 +97,7 @@ public void testSetRedis() Assert.assertNotNull("Redis instance could not be created", redis); String cacheId = "TEST"; - String cacheKey = "TEST_KEY"; + String cacheKey = "TEST_KEY" + ThreadLocalRandom.current().nextInt(); String cacheValue = "KeyValue"; redis.set(cacheId, cacheKey, cacheValue); @@ -112,8 +113,8 @@ public void testSetCacheValueRedis() RedisClient redis = getRedisClient("", ""); Assert.assertNotNull("Redis instance could not be created", redis); - String cacheId = "TEST"; - String cacheKey = "TEST_KEY"; + String cacheId = "TEST"+ ThreadLocalRandom.current().nextInt(); + String cacheKey = "TEST_KEY" + ThreadLocalRandom.current().nextInt(); CacheValue c = new CacheValue("SELECT * FROM User;", new Object[] { 1, 2, 3}); c.addItem(123); redis.set(cacheId, cacheKey, c); From 2a59f75c3c41a1968c984a6e7d3d3b73ba811fb8 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Fri, 27 May 2022 15:09:40 -0300 Subject: [PATCH 3/7] try fix redis serialization error --- java/src/main/java/com/genexus/cache/redis/RedisClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/src/main/java/com/genexus/cache/redis/RedisClient.java b/java/src/main/java/com/genexus/cache/redis/RedisClient.java index f8abe4d48..003871ca7 100644 --- a/java/src/main/java/com/genexus/cache/redis/RedisClient.java +++ b/java/src/main/java/com/genexus/cache/redis/RedisClient.java @@ -81,7 +81,6 @@ private void initCache(String hostOrRedisURL, String password, String cacheKeyPa objMapper = new ObjectMapper(); objMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); objMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - objMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); objMapper.enable(SerializationFeature.INDENT_OUTPUT); } From 7846a96a1aa5d87a0e9288abda8b0354d405b605 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Fri, 27 May 2022 15:13:58 -0300 Subject: [PATCH 4/7] try fix redis serialization error --- .../com/genexus/cache/redis/RedisClient.java | 7 +- .../main/java/com/genexus/db/CacheValue.java | 67 +++++++++---------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/java/src/main/java/com/genexus/cache/redis/RedisClient.java b/java/src/main/java/com/genexus/cache/redis/RedisClient.java index 003871ca7..1113f74d4 100644 --- a/java/src/main/java/com/genexus/cache/redis/RedisClient.java +++ b/java/src/main/java/com/genexus/cache/redis/RedisClient.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonAutoDetect; import org.apache.commons.lang.StringUtils; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; @@ -79,7 +80,11 @@ private void initCache(String hostOrRedisURL, String password, String cacheKeyPa pool = new JedisPool(new JedisPoolConfig(), host, port, redis.clients.jedis.Protocol.DEFAULT_TIMEOUT, password); objMapper = new ObjectMapper(); - objMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); + objMapper + .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY) + .setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE) + .setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE) + .setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.NONE); objMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); objMapper.enable(SerializationFeature.INDENT_OUTPUT); } diff --git a/java/src/main/java/com/genexus/db/CacheValue.java b/java/src/main/java/com/genexus/db/CacheValue.java index 0f7106996..f48cb5c96 100644 --- a/java/src/main/java/com/genexus/db/CacheValue.java +++ b/java/src/main/java/com/genexus/db/CacheValue.java @@ -1,6 +1,4 @@ package com.genexus.db; -import com.fasterxml.jackson.annotation.JsonIgnore; - import java.io.Serializable; import java.util.Enumeration; import java.util.TimeZone; @@ -25,7 +23,7 @@ public class CacheValue implements Serializable public CacheValue() { - } + } public CacheValue(String sentence, Object [] parms) { if(parms == null) @@ -39,15 +37,15 @@ public CacheValue(String sentence, Object [] parms) key = new CacheKey(sentence, keyParms); } items = new Vector(); - + cachedSize = sentence.length(); } - + public CacheKey getKey() { return key; } - + /** Setea el tiempo de expiración (en segundos) * o 0 para indicar que no expira por tiempo */ @@ -55,7 +53,7 @@ public void setExpiryTime(int expiryTimeSeconds) { this.expiryTime = expiryTimeSeconds; } - + public long getExpiryTimeMilliseconds() { return expiryTime*1000; @@ -64,30 +62,30 @@ public int getExpiryTimeSeconds() { return expiryTime; } - + /** Setea la cantidad de hits para expirar, o 0 si no * expira por cantidad de hits - */ + */ public void setExpiryHits(int expiryHits) { this.expiryHits = expiryHits; } - + public int getExpiryHits() { return expiryHits; - } - + } + /** Indica si este CacheValue ha expirado */ public boolean hasExpired() { - return (expiryHits > 0 && hits >= expiryHits) || + return (expiryHits > 0 && hits >= expiryHits) || (expiryTime > 0 && (timestamp + (getExpiryTimeMilliseconds())) < System.currentTimeMillis()); } - + private int []resultSetTypes; - + private void getResultSetTypes(Object [] resultSet) { resultSetTypes = new int[resultSet.length]; @@ -97,12 +95,12 @@ private void getResultSetTypes(Object [] resultSet) resultSetTypes[i] = DynamicExecute.getPrimitiveType(componentType); } } - - public void setTimeZone(TimeZone cachedValueTimeZone) + + public void setTimeZone(TimeZone cachedValueTimeZone) { mTimeZone = cachedValueTimeZone; } - + protected void setIsRemote(boolean isRemote) { this.isRemote = isRemote; @@ -129,11 +127,11 @@ public void addItem(T value) items.addElement(new CachedIFieldGetter(values)); } } - + public void addItem(Object [] resultSet, long thisSize) { cachedSize += thisSize + 8 * resultSet.length; - + // @HACK // Tenemos que hacer un deep copy del resultSet // pero como usamos tipos primitivos no podemos hacer el arrayCopy @@ -142,7 +140,7 @@ public void addItem(Object [] resultSet, long thisSize) if(resultSetTypes == null) { getResultSetTypes(resultSet); - } + } Object [] copy = (Object[])resultSet.clone(); for(int i = 0; i < resultSet.length; i++) { @@ -156,7 +154,7 @@ public void addItem(Object [] resultSet, long thisSize) case DynamicExecute.TYPE_FLOAT: copy[i] = ((float[])resultSet[i]).clone(); break; case DynamicExecute.TYPE_DOUBLE: copy[i] = ((double[])resultSet[i]).clone(); break; case DynamicExecute.TYPE_BOOLEAN: copy[i] = ((boolean[])resultSet[i]).clone(); break; - default: + default: copy[i] = ((Object[])resultSet[i]).clone(); System.arraycopy(resultSet[i], 0, copy[i], 0, 1); } @@ -165,39 +163,38 @@ public void addItem(Object [] resultSet, long thisSize) cValue.setTimeZone(mTimeZone); items.addElement(cValue); } - + public void setTimestamp() { timestamp = System.currentTimeMillis(); setTimeCreated(new java.util.Date()); } - + public long getTimestamp() { return timestamp; } - - @JsonIgnore + //IFieldGetter iterator public Enumeration getIterator() { return items.elements(); } - + protected void incHits() { hits++; } - + public int getHitCount() { return hits; } - + protected int getCantItems() { return items.size(); } - + /** Retorna una estimación del 'tamaño' de este cacheValue * En 2 capas, el tamaño del CacheValue lo contamos como la cantidad de filas * multiplicado por la cantidad de columnas @@ -207,16 +204,16 @@ public long getSize() { return cachedSize; } - + public java.util.Date getTimeCreated() { return timeCreated; } - + public void setTimeCreated(java.util.Date timeCreated) { this.timeCreated = timeCreated; - } - - + } + + } From 5f4491ea6ad58d018dc74a10c6519290c9d34ae2 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Fri, 27 May 2022 15:16:04 -0300 Subject: [PATCH 5/7] Restore original cache value --- java/src/main/java/com/genexus/db/CacheValue.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/java/src/main/java/com/genexus/db/CacheValue.java b/java/src/main/java/com/genexus/db/CacheValue.java index f48cb5c96..7bac86d0f 100644 --- a/java/src/main/java/com/genexus/db/CacheValue.java +++ b/java/src/main/java/com/genexus/db/CacheValue.java @@ -55,7 +55,7 @@ public void setExpiryTime(int expiryTimeSeconds) } public long getExpiryTimeMilliseconds() - { + { return expiryTime*1000; } public int getExpiryTimeSeconds() @@ -80,8 +80,8 @@ public int getExpiryHits() */ public boolean hasExpired() { - return (expiryHits > 0 && hits >= expiryHits) || - (expiryTime > 0 && (timestamp + (getExpiryTimeMilliseconds())) < System.currentTimeMillis()); + return (expiryHits > 0 && hits >= expiryHits) || + (expiryTime > 0 && (timestamp + (getExpiryTimeMilliseconds())) < System.currentTimeMillis()); } private int []resultSetTypes; @@ -155,8 +155,8 @@ public void addItem(Object [] resultSet, long thisSize) case DynamicExecute.TYPE_DOUBLE: copy[i] = ((double[])resultSet[i]).clone(); break; case DynamicExecute.TYPE_BOOLEAN: copy[i] = ((boolean[])resultSet[i]).clone(); break; default: - copy[i] = ((Object[])resultSet[i]).clone(); - System.arraycopy(resultSet[i], 0, copy[i], 0, 1); + copy[i] = ((Object[])resultSet[i]).clone(); + System.arraycopy(resultSet[i], 0, copy[i], 0, 1); } } CachedIFieldGetter cValue = new CachedIFieldGetter(copy); @@ -216,4 +216,4 @@ public void setTimeCreated(java.util.Date timeCreated) } -} +} \ No newline at end of file From a5dfd8cca855580d1e6f96020f70e6debb20646c Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Fri, 27 May 2022 15:19:33 -0300 Subject: [PATCH 6/7] Restore original cache value --- .../main/java/com/genexus/db/CacheValue.java | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/java/src/main/java/com/genexus/db/CacheValue.java b/java/src/main/java/com/genexus/db/CacheValue.java index 7bac86d0f..fd3d89e90 100644 --- a/java/src/main/java/com/genexus/db/CacheValue.java +++ b/java/src/main/java/com/genexus/db/CacheValue.java @@ -23,7 +23,7 @@ public class CacheValue implements Serializable public CacheValue() { - } + } public CacheValue(String sentence, Object [] parms) { if(parms == null) @@ -37,15 +37,15 @@ public CacheValue(String sentence, Object [] parms) key = new CacheKey(sentence, keyParms); } items = new Vector(); - + cachedSize = sentence.length(); } - + public CacheKey getKey() { return key; } - + /** Setea el tiempo de expiración (en segundos) * o 0 para indicar que no expira por tiempo */ @@ -53,39 +53,39 @@ public void setExpiryTime(int expiryTimeSeconds) { this.expiryTime = expiryTimeSeconds; } - + public long getExpiryTimeMilliseconds() - { + { return expiryTime*1000; } public int getExpiryTimeSeconds() { return expiryTime; } - + /** Setea la cantidad de hits para expirar, o 0 si no * expira por cantidad de hits - */ + */ public void setExpiryHits(int expiryHits) { this.expiryHits = expiryHits; } - + public int getExpiryHits() { return expiryHits; - } - + } + /** Indica si este CacheValue ha expirado */ public boolean hasExpired() { - return (expiryHits > 0 && hits >= expiryHits) || - (expiryTime > 0 && (timestamp + (getExpiryTimeMilliseconds())) < System.currentTimeMillis()); + return (expiryHits > 0 && hits >= expiryHits) || + (expiryTime > 0 && (timestamp + (getExpiryTimeMilliseconds())) < System.currentTimeMillis()); } - + private int []resultSetTypes; - + private void getResultSetTypes(Object [] resultSet) { resultSetTypes = new int[resultSet.length]; @@ -95,12 +95,12 @@ private void getResultSetTypes(Object [] resultSet) resultSetTypes[i] = DynamicExecute.getPrimitiveType(componentType); } } - - public void setTimeZone(TimeZone cachedValueTimeZone) + + public void setTimeZone(TimeZone cachedValueTimeZone) { mTimeZone = cachedValueTimeZone; } - + protected void setIsRemote(boolean isRemote) { this.isRemote = isRemote; @@ -127,11 +127,11 @@ public void addItem(T value) items.addElement(new CachedIFieldGetter(values)); } } - + public void addItem(Object [] resultSet, long thisSize) { cachedSize += thisSize + 8 * resultSet.length; - + // @HACK // Tenemos que hacer un deep copy del resultSet // pero como usamos tipos primitivos no podemos hacer el arrayCopy @@ -140,7 +140,7 @@ public void addItem(Object [] resultSet, long thisSize) if(resultSetTypes == null) { getResultSetTypes(resultSet); - } + } Object [] copy = (Object[])resultSet.clone(); for(int i = 0; i < resultSet.length; i++) { @@ -154,47 +154,47 @@ public void addItem(Object [] resultSet, long thisSize) case DynamicExecute.TYPE_FLOAT: copy[i] = ((float[])resultSet[i]).clone(); break; case DynamicExecute.TYPE_DOUBLE: copy[i] = ((double[])resultSet[i]).clone(); break; case DynamicExecute.TYPE_BOOLEAN: copy[i] = ((boolean[])resultSet[i]).clone(); break; - default: - copy[i] = ((Object[])resultSet[i]).clone(); - System.arraycopy(resultSet[i], 0, copy[i], 0, 1); + default: + copy[i] = ((Object[])resultSet[i]).clone(); + System.arraycopy(resultSet[i], 0, copy[i], 0, 1); } } CachedIFieldGetter cValue = new CachedIFieldGetter(copy); cValue.setTimeZone(mTimeZone); items.addElement(cValue); } - + public void setTimestamp() { timestamp = System.currentTimeMillis(); setTimeCreated(new java.util.Date()); } - + public long getTimestamp() { return timestamp; - } + } //IFieldGetter iterator public Enumeration getIterator() { return items.elements(); } - + protected void incHits() { hits++; } - + public int getHitCount() { return hits; } - + protected int getCantItems() { return items.size(); } - + /** Retorna una estimación del 'tamaño' de este cacheValue * En 2 capas, el tamaño del CacheValue lo contamos como la cantidad de filas * multiplicado por la cantidad de columnas @@ -204,16 +204,16 @@ public long getSize() { return cachedSize; } - + public java.util.Date getTimeCreated() { return timeCreated; } - + public void setTimeCreated(java.util.Date timeCreated) { this.timeCreated = timeCreated; - } - - -} \ No newline at end of file + } + + +} From 54f6de1c94d21d587e5dee79a238a0554364d991 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Wed, 1 Jun 2022 10:19:27 -0300 Subject: [PATCH 7/7] Remove unused import --- java/src/main/java/com/genexus/cache/redis/RedisClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/src/main/java/com/genexus/cache/redis/RedisClient.java b/java/src/main/java/com/genexus/cache/redis/RedisClient.java index 1113f74d4..372e3665d 100644 --- a/java/src/main/java/com/genexus/cache/redis/RedisClient.java +++ b/java/src/main/java/com/genexus/cache/redis/RedisClient.java @@ -10,7 +10,6 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect; import org.apache.commons.lang.StringUtils; -import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper;