diff --git a/core-scala/src/test/scala/com/baeldung/scala/RegexUnitTest.scala b/core-scala/src/test/scala/com/baeldung/scala/RegexUnitTest.scala
new file mode 100644
index 0000000000..94263d620a
--- /dev/null
+++ b/core-scala/src/test/scala/com/baeldung/scala/RegexUnitTest.scala
@@ -0,0 +1,73 @@
+package com.baeldung.scala
+
+import org.junit.Test
+import org.junit.Assert.assertEquals
+
+class RegexUnitTest {
+ private val polishPostalCode = "([0-9]{2})\\-([0-9]{3})".r
+ private val timestamp = "([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{3})".r
+ private val timestampUnanchored = timestamp.unanchored
+
+ @Test
+ def givenRegularExpression_whenCallingFindFirstIn_thenShouldFindCorrectMatches(): Unit = {
+ val postCode = polishPostalCode.findFirstIn("Warsaw 01-011, Jerusalem Avenue")
+ assertEquals(Some("01-011"), postCode)
+ }
+
+ @Test
+ def givenRegularExpression_whenCallingFindFirstMatchIn_thenShouldFindCorrectMatches(): Unit = {
+ val postCodes = polishPostalCode.findFirstMatchIn("Warsaw 01-011, Jerusalem Avenue")
+ assertEquals(Some("011"), for (m <- postCodes) yield m.group(2))
+ }
+
+ @Test
+ def givenRegularExpression_whenCallingFindAllIn_thenShouldFindCorrectMatches(): Unit = {
+ val postCodes = polishPostalCode.findAllIn("Warsaw 01-011, Jerusalem Avenue, Cracow 30-059, Mickiewicza Avenue")
+ .toList
+ assertEquals(List("01-011", "30-059"), postCodes)
+
+ polishPostalCode.findAllIn("Warsaw 01-011, Jerusalem Avenue, Cracow 30-059, Mickiewicza Avenue")
+ }
+
+ @Test
+ def givenRegularExpression_whenCallingFindAlMatchlIn_thenShouldFindCorrectMatches(): Unit = {
+ val postCodes = polishPostalCode.findAllMatchIn("Warsaw 01-011, Jerusalem Avenue, Cracow 30-059, Mickiewicza Avenue")
+ .toList
+ val postalDistricts = for (m <- postCodes) yield m.group(1)
+ assertEquals(List("01", "30"), postalDistricts)
+ }
+
+ @Test
+ def givenRegularExpression_whenExtractingValues_thenShouldExtractCorrectValues(): Unit = {
+ val description = "11:34:01.411" match {
+ case timestamp(hour, minutes, _, _) => s"It's $minutes minutes after $hour"
+ }
+
+ assertEquals("It's 34 minutes after 11", description)
+ }
+
+ @Test
+ def givenUnanchoredRegularExpression_whenExtractingValues_thenShouldExtractCorrectValues(): Unit = {
+ val description = "Timestamp: 11:34:01.411 error appeared" match {
+ case timestampUnanchored(hour, minutes, _, _) => s"It's $minutes minutes after $hour"
+ }
+
+ assertEquals("It's 34 minutes after 11", description)
+ }
+
+ @Test
+ def givenRegularExpression_whenCallingReplaceAllIn_thenShouldReplaceText(): Unit = {
+ val minutes = timestamp.replaceAllIn("11:34:01.311", m => m.group(2))
+
+ assertEquals("34", minutes)
+ }
+
+ @Test
+ def givenRegularExpression_whenCallingReplaceAllInWithMatcher_thenShouldReplaceText(): Unit = {
+ val secondsThatDayInTotal = timestamp.replaceAllIn("11:34:01.311", _ match {
+ case timestamp(hours, minutes, seconds, _) => s"$hours-$minutes"
+ })
+
+ assertEquals("11-34", secondsThatDayInTotal)
+ }
+}
diff --git a/json-2/README.md b/json-2/README.md
new file mode 100644
index 0000000000..e7c3043339
--- /dev/null
+++ b/json-2/README.md
@@ -0,0 +1,5 @@
+## JSON
+
+This module contains articles about JSON.
+
+### Relevant Articles:
diff --git a/json-2/pom.xml b/json-2/pom.xml
new file mode 100644
index 0000000000..72b3295b2b
--- /dev/null
+++ b/json-2/pom.xml
@@ -0,0 +1,41 @@
+
+
+ com.baeldung
+ json-2
+ 0.0.1-SNAPSHOT
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+
+
+
+ com.jsoniter
+ jsoniter
+ ${jsoniter.version}
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj-core.version}
+ test
+
+
+
+ 0.9.23
+ 3.11.1
+
+
diff --git a/json-2/src/main/java/com/baeldung/jsoniter/model/Name.java b/json-2/src/main/java/com/baeldung/jsoniter/model/Name.java
new file mode 100644
index 0000000000..ed5e221235
--- /dev/null
+++ b/json-2/src/main/java/com/baeldung/jsoniter/model/Name.java
@@ -0,0 +1,22 @@
+package com.baeldung.jsoniter.model;
+
+public class Name {
+ private String firstName;
+ private String surname;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getSurname() {
+ return surname;
+ }
+
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+}
diff --git a/json-2/src/main/java/com/baeldung/jsoniter/model/Student.java b/json-2/src/main/java/com/baeldung/jsoniter/model/Student.java
new file mode 100644
index 0000000000..07c73dd18e
--- /dev/null
+++ b/json-2/src/main/java/com/baeldung/jsoniter/model/Student.java
@@ -0,0 +1,26 @@
+package com.baeldung.jsoniter.model;
+
+import com.jsoniter.annotation.JsonProperty;
+import com.jsoniter.fuzzy.MaybeStringIntDecoder;
+
+public class Student {
+ @JsonProperty(decoder = MaybeStringIntDecoder.class)
+ private int id;
+ private Name name;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public Name getName() {
+ return name;
+ }
+
+ public void setName(Name name) {
+ this.name = name;
+ }
+}
diff --git a/json-2/src/test/java/com/baeldung/jsoniter/JsoniterIntroUnitTest.java b/json-2/src/test/java/com/baeldung/jsoniter/JsoniterIntroUnitTest.java
new file mode 100644
index 0000000000..09f82567a2
--- /dev/null
+++ b/json-2/src/test/java/com/baeldung/jsoniter/JsoniterIntroUnitTest.java
@@ -0,0 +1,85 @@
+package com.baeldung.jsoniter;
+
+import com.baeldung.jsoniter.model.Name;
+import com.baeldung.jsoniter.model.Student;
+import com.jsoniter.JsonIterator;
+import com.jsoniter.ValueType;
+import com.jsoniter.any.Any;
+
+import org.junit.Test;
+
+import static com.jsoniter.ValueType.STRING;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class JsoniterIntroUnitTest {
+
+ @Test
+ public void whenParsedUsingBindAPI_thenConvertedToJavaObjectCorrectly() {
+ String input = "{\"id\":1,\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
+
+ Student student = JsonIterator.deserialize(input, Student.class);
+
+ assertThat(student.getId()).isEqualTo(1);
+ assertThat(student.getName().getFirstName()).isEqualTo("Joe");
+ assertThat(student.getName().getSurname()).isEqualTo("Blogg");
+ }
+
+ @Test
+ public void givenTypeInJsonFuzzy_whenFieldIsMaybeDecoded_thenFieldParsedCorrectly() {
+ String input = "{\"id\":\"1\",\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
+
+ Student student = JsonIterator.deserialize(input, Student.class);
+
+ assertThat(student.getId()).isEqualTo(1);
+ }
+
+ @Test
+ public void whenParsedUsingAnyAPI_thenFieldValueCanBeExtractedUsingTheFieldName() {
+ String input = "{\"id\":1,\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
+
+ Any any = JsonIterator.deserialize(input);
+
+ assertThat(any.toInt("id")).isEqualTo(1);
+ assertThat(any.toString("name", "firstName")).isEqualTo("Joe");
+ assertThat(any.toString("name", "surname")).isEqualTo("Blogg");
+ }
+
+ @Test
+ public void whenParsedUsingAnyAPI_thenFieldValueTypeIsCorrect() {
+ String input = "{\"id\":1,\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
+
+ Any any = JsonIterator.deserialize(input);
+
+ assertThat(any.get("id").valueType()).isEqualTo(ValueType.NUMBER);
+ assertThat(any.get("name").valueType()).isEqualTo(ValueType.OBJECT);
+ assertThat(any.get("error").valueType()).isEqualTo(ValueType.INVALID);
+ }
+
+ @Test
+ public void whenParsedUsingIteratorAPI_thenFieldValuesExtractedCorrectly() throws Exception {
+ Name name = new Name();
+ String input = "{ \"firstName\" : \"Joe\", \"surname\" : \"Blogg\" }";
+ JsonIterator iterator = JsonIterator.parse(input);
+
+ for (String field = iterator.readObject(); field != null; field = iterator.readObject()) {
+ switch (field) {
+ case "firstName":
+ if (iterator.whatIsNext() == ValueType.STRING) {
+ name.setFirstName(iterator.readString());
+ }
+ continue;
+ case "surname":
+ if (iterator.whatIsNext() == ValueType.STRING) {
+ name.setSurname(iterator.readString());
+ }
+ continue;
+ default:
+ iterator.skip();
+ }
+ }
+
+ assertThat(name.getFirstName()).isEqualTo("Joe");
+ assertThat(name.getSurname()).isEqualTo("Blogg");
+ }
+
+}
diff --git a/json-2/src/test/resources/Student.json b/json-2/src/test/resources/Student.json
new file mode 100644
index 0000000000..7ff3351e8e
--- /dev/null
+++ b/json-2/src/test/resources/Student.json
@@ -0,0 +1 @@
+{"id":1,"name":{"firstName": "Joe", "surname":"Blogg"}}
diff --git a/persistence-modules/redis/pom.xml b/persistence-modules/redis/pom.xml
index c4a928bb4a..98b8ef30f3 100644
--- a/persistence-modules/redis/pom.xml
+++ b/persistence-modules/redis/pom.xml
@@ -38,7 +38,7 @@
- 2.9.0
+ 3.2.0
0.6
3.3.0
5.0.1.RELEASE
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/client/RedisClient.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/client/RedisClient.java
new file mode 100644
index 0000000000..2fe7a787e0
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/client/RedisClient.java
@@ -0,0 +1,149 @@
+package com.baeldung.redis_scan.client;
+
+import com.baeldung.redis_scan.iterator.RedisIterator;
+import com.baeldung.redis_scan.strategy.ScanStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+
+public class RedisClient {
+ private static Logger log = LoggerFactory.getLogger(RedisClient.class);
+
+ private static volatile RedisClient instance = null;
+
+ private static JedisPool jedisPool;
+
+ public static RedisClient getInstance(String ip, final int port) {
+ if (instance == null) {
+ synchronized (RedisClient.class) {
+ if (instance == null) {
+ instance = new RedisClient(ip, port);
+ }
+ }
+ }
+ return instance;
+ }
+
+ private RedisClient(String ip, int port) {
+ try {
+ if (jedisPool == null) {
+ jedisPool = new JedisPool(new URI("http://" + ip + ":" + port));
+ }
+ } catch (URISyntaxException e) {
+ log.error("Malformed server address", e);
+ }
+ }
+
+ public Long lpush(final String key, final String[] strings) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ return jedis.lpush(key, strings);
+ } catch (Exception ex) {
+ log.error("Exception caught in lpush", ex);
+ }
+ return null;
+ }
+
+ public List lrange(final String key, final long start, final long stop) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ return jedis.lrange(key, start, stop);
+ } catch (Exception ex) {
+ log.error("Exception caught in lrange", ex);
+ }
+ return new LinkedList();
+ }
+
+ public String hmset(final String key, final Map hash) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ return jedis.hmset(key, hash);
+ } catch (Exception ex) {
+ log.error("Exception caught in hmset", ex);
+ }
+ return null;
+ }
+
+ public Map hgetAll(final String key) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ return jedis.hgetAll(key);
+ } catch (Exception ex) {
+ log.error("Exception caught in hgetAll", ex);
+ }
+ return new HashMap();
+ }
+
+ public Long sadd(final String key, final String... members) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ return jedis.sadd(key, members);
+ } catch (Exception ex) {
+ log.error("Exception caught in sadd", ex);
+ }
+ return null;
+ }
+
+ public Set smembers(final String key) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ return jedis.smembers(key);
+ } catch (Exception ex) {
+ log.error("Exception caught in smembers", ex);
+ }
+ return new HashSet();
+ }
+
+ public Long zadd(final String key, final Map scoreMembers) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ return jedis.zadd(key, scoreMembers);
+ } catch (Exception ex) {
+ log.error("Exception caught in zadd", ex);
+ }
+ return 0L;
+ }
+
+ public Set zrange(final String key, final long start, final long stop) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ return jedis.zrange(key, start, stop);
+ } catch (Exception ex) {
+ log.error("Exception caught in zrange", ex);
+ }
+ return new HashSet();
+ }
+
+ public String mset(final HashMap keysValues) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ ArrayList keysValuesArrayList = new ArrayList();
+ keysValues.forEach((key, value) -> {
+ keysValuesArrayList.add(key);
+ keysValuesArrayList.add(value);
+ });
+ return jedis.mset((keysValuesArrayList.toArray(new String[keysValues.size()])));
+ } catch (Exception ex) {
+ log.error("Exception caught in mset", ex);
+ }
+ return null;
+ }
+
+ public Set keys(final String pattern) {
+ try (Jedis jedis = jedisPool.getResource()) {
+ return jedis.keys(pattern);
+ } catch (Exception ex) {
+ log.error("Exception caught in keys", ex);
+ }
+ return new HashSet();
+ }
+
+ public RedisIterator iterator(int initialScanCount, String pattern, ScanStrategy strategy) {
+ return new RedisIterator(jedisPool, initialScanCount, pattern, strategy);
+ }
+
+ public void flushAll() {
+ try (Jedis jedis = jedisPool.getResource()) {
+ jedis.flushAll();
+ } catch (Exception ex) {
+ log.error("Exception caught in flushAll", ex);
+ }
+ }
+
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/iterator/RedisIterator.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/iterator/RedisIterator.java
new file mode 100644
index 0000000000..5fbd798ac2
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/iterator/RedisIterator.java
@@ -0,0 +1,60 @@
+package com.baeldung.redis_scan.iterator;
+
+import com.baeldung.redis_scan.strategy.ScanStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.ScanParams;
+import redis.clients.jedis.ScanResult;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class RedisIterator implements Iterator> {
+
+ private static Logger log = LoggerFactory.getLogger(RedisIterator.class);
+ private static final int DEFAULT_SCAN_COUNT = 10;
+
+ private final JedisPool jedisPool;
+ private ScanParams scanParams;
+ private String cursor;
+ private ScanStrategy strategy;
+
+ public RedisIterator(JedisPool jedisPool, int initialScanCount, String pattern, ScanStrategy strategy) {
+ super();
+ this.jedisPool = jedisPool;
+ this.scanParams = new ScanParams().match(pattern).count(initialScanCount);
+ this.strategy = strategy;
+ }
+
+ public RedisIterator(JedisPool jedisPool, String pattern, ScanStrategy strategy) {
+ super();
+ this.jedisPool = jedisPool;
+ this.scanParams = new ScanParams().match(pattern).count(DEFAULT_SCAN_COUNT);
+ this.strategy = strategy;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !"0".equals(cursor);
+ }
+
+ @Override
+ public List next() {
+ if (cursor == null) {
+ cursor = "0";
+ }
+ try (Jedis jedis = jedisPool.getResource()) {
+ ScanResult scanResult = strategy.scan(jedis, cursor, scanParams);
+ cursor = scanResult.getCursor();
+ return scanResult.getResult();
+
+ } catch (Exception ex) {
+ log.error("Exception caught in next()", ex);
+ }
+ return new LinkedList();
+ }
+
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/ScanStrategy.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/ScanStrategy.java
new file mode 100644
index 0000000000..39d9e44a63
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/ScanStrategy.java
@@ -0,0 +1,9 @@
+package com.baeldung.redis_scan.strategy;
+
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.ScanParams;
+import redis.clients.jedis.ScanResult;
+
+public interface ScanStrategy {
+ ScanResult scan(Jedis jedis, String cursor, ScanParams scanParams);
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Hscan.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Hscan.java
new file mode 100644
index 0000000000..fd5ecd14ec
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Hscan.java
@@ -0,0 +1,25 @@
+package com.baeldung.redis_scan.strategy.impl;
+
+import com.baeldung.redis_scan.strategy.ScanStrategy;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.ScanParams;
+import redis.clients.jedis.ScanResult;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class Hscan implements ScanStrategy> {
+
+ private String key;
+
+ public Hscan(String key) {
+ super();
+ this.key = key;
+ }
+
+ @Override
+ public ScanResult> scan(Jedis jedis, String cursor, ScanParams scanParams) {
+ return jedis.hscan(key, cursor, scanParams);
+ }
+
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Scan.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Scan.java
new file mode 100644
index 0000000000..f28b56e34c
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Scan.java
@@ -0,0 +1,14 @@
+package com.baeldung.redis_scan.strategy.impl;
+
+import com.baeldung.redis_scan.strategy.ScanStrategy;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.ScanParams;
+import redis.clients.jedis.ScanResult;
+
+public class Scan implements ScanStrategy {
+
+
+ public ScanResult scan(Jedis jedis, String cursor, ScanParams scanParams) {
+ return jedis.scan(cursor, scanParams);
+ }
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Sscan.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Sscan.java
new file mode 100644
index 0000000000..ed47f7087e
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Sscan.java
@@ -0,0 +1,29 @@
+package com.baeldung.redis_scan.strategy.impl;
+
+import com.baeldung.redis_scan.strategy.ScanStrategy;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.ScanParams;
+import redis.clients.jedis.ScanResult;
+
+public class Sscan implements ScanStrategy {
+
+ private String key;
+
+
+ public Sscan(String key) {
+ super();
+ this.key = key;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public ScanResult scan(Jedis jedis, String cursor, ScanParams scanParams) {
+ return jedis.sscan(key, cursor, scanParams);
+ }
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Zscan.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Zscan.java
new file mode 100644
index 0000000000..bdffc15883
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Zscan.java
@@ -0,0 +1,25 @@
+package com.baeldung.redis_scan.strategy.impl;
+
+import com.baeldung.redis_scan.strategy.ScanStrategy;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.ScanParams;
+import redis.clients.jedis.ScanResult;
+import redis.clients.jedis.Tuple;
+
+public class Zscan implements ScanStrategy {
+
+ private String key;
+
+
+ public Zscan(String key) {
+ super();
+ this.key = key;
+ }
+
+
+ @Override
+ public ScanResult scan(Jedis jedis, String cursor, ScanParams scanParams) {
+ return jedis.zscan(key, cursor, scanParams);
+ }
+
+}
diff --git a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java
new file mode 100644
index 0000000000..c24b88e20c
--- /dev/null
+++ b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java
@@ -0,0 +1,96 @@
+package com.baeldung.redis_scan;
+
+import com.baeldung.redis_scan.client.RedisClient;
+import org.junit.*;
+import redis.embedded.RedisServer;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class NaiveApproachIntegrationTest {
+ private static RedisServer redisServer;
+ private static int port;
+ private static RedisClient redisClient;
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+
+ // Take an available port
+ ServerSocket s = new ServerSocket(0);
+ port = s.getLocalPort();
+ s.close();
+
+ redisServer = new RedisServer(port);
+ redisServer.start();
+ }
+
+ @AfterClass
+ public static void destroy() {
+ if (redisServer.isActive())
+ redisServer.stop();
+ }
+
+ @Before
+ public void init() {
+ if (!redisServer.isActive()) {
+ redisServer.start();
+ }
+ redisClient = RedisClient.getInstance("127.0.0.1", port);
+ }
+
+ @After
+ public void flushAll() {
+ redisClient.flushAll();
+ }
+
+ @Test
+ public void testKeys() {
+ HashMap keyValues = new HashMap();
+ keyValues.put("balls:cricket", "160");
+ keyValues.put("balls:football", "450");
+ keyValues.put("balls:volleyball", "270");
+ redisClient.mset(keyValues);
+ Set readKeys = redisClient.keys("ball*");
+ Assert.assertEquals(keyValues.size(), readKeys.size());
+
+ }
+
+ @Test
+ public void testSmembers() {
+ HashSet setMembers = new HashSet();
+ setMembers.add("cricket_160");
+ setMembers.add("football_450");
+ setMembers.add("volleyball_270");
+ redisClient.sadd("balls", setMembers.toArray(new String[setMembers.size()]));
+ Set readSetMembers = redisClient.smembers("balls");
+ Assert.assertEquals(setMembers.size(), readSetMembers.size());
+ }
+
+ @Test
+ public void testHgetAll() {
+ HashMap keyValues = new HashMap();
+ keyValues.put("balls:cricket", "160");
+ keyValues.put("balls:football", "450");
+ keyValues.put("balls:volleyball", "270");
+ redisClient.hmset("balls", keyValues);
+ Map readHash = redisClient.hgetAll("balls");
+ Assert.assertEquals(keyValues.size(), readHash.size());
+ }
+
+ @Test
+ public void testZRange() {
+ HashMap scoreMembers = new HashMap();
+ scoreMembers.put("cricket", (double) 160);
+ scoreMembers.put("football", (double) 450);
+ scoreMembers.put("volleyball", (double) 270);
+ redisClient.zadd("balls", scoreMembers);
+ Set readSetMembers = redisClient.zrange("balls", 0, -1);
+
+ Assert.assertEquals(readSetMembers.size(), scoreMembers.size());
+ }
+
+}
diff --git a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java
new file mode 100644
index 0000000000..828b7a3183
--- /dev/null
+++ b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java
@@ -0,0 +1,129 @@
+package com.baeldung.redis_scan;
+
+import com.baeldung.redis_scan.client.RedisClient;
+import com.baeldung.redis_scan.iterator.RedisIterator;
+import com.baeldung.redis_scan.strategy.ScanStrategy;
+import com.baeldung.redis_scan.strategy.impl.Hscan;
+import com.baeldung.redis_scan.strategy.impl.Scan;
+import com.baeldung.redis_scan.strategy.impl.Sscan;
+import com.baeldung.redis_scan.strategy.impl.Zscan;
+import org.junit.*;
+import redis.clients.jedis.Tuple;
+import redis.embedded.RedisServer;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.*;
+
+
+public class ScanStrategyIntegrationTest {
+
+ private static RedisServer redisServer;
+ private static int port;
+ private static RedisClient redisClient;
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+
+ // Take an available port
+ ServerSocket s = new ServerSocket(0);
+ String ip = "127.0.0.1";
+ port = s.getLocalPort();
+ s.close();
+
+ redisServer = new RedisServer(port);
+ redisServer.start();
+ }
+
+ @AfterClass
+ public static void destroy() {
+ if (redisServer.isActive())
+ redisServer.stop();
+ }
+
+ @Before
+ public void init() {
+ if (!redisServer.isActive()) {
+ redisServer.start();
+ }
+ redisClient = RedisClient.getInstance("127.0.0.1", port);
+ }
+
+ @After
+ public void flushAll() {
+ redisClient.flushAll();
+ }
+
+ @Test
+ public void testScanStrategy() {
+ HashMap keyValues = new HashMap();
+ keyValues.put("balls:cricket", "160");
+ keyValues.put("balls:football", "450");
+ keyValues.put("balls:volleyball", "270");
+ redisClient.mset(keyValues);
+
+ ScanStrategy scanStrategy = new Scan();
+ int iterationCount = 2;
+ RedisIterator iterator = redisClient.iterator(iterationCount, "ball*", scanStrategy);
+ List results = new LinkedList();
+ while (iterator.hasNext()) {
+ results.addAll(iterator.next());
+ }
+ Assert.assertEquals(keyValues.size(), results.size());
+ }
+
+ @Test
+ public void testSscanStrategy() {
+ HashSet setMembers = new HashSet();
+ setMembers.add("cricket_160");
+ setMembers.add("football_450");
+ setMembers.add("volleyball_270");
+ redisClient.sadd("balls", setMembers.toArray(new String[setMembers.size()]));
+
+ Sscan scanStrategy = new Sscan("balls");
+ int iterationCount = 2;
+ RedisIterator iterator = redisClient.iterator(iterationCount, "*", scanStrategy);
+ List results = new LinkedList();
+ while (iterator.hasNext()) {
+ results.addAll(iterator.next());
+ }
+ Assert.assertEquals(setMembers.size(), results.size());
+ }
+
+ @Test
+ public void testHscanStrategy() {
+ HashMap hash = new HashMap();
+ hash.put("cricket", "160");
+ hash.put("football", "450");
+ hash.put("volleyball", "270");
+ redisClient.hmset("balls", hash);
+
+ Hscan scanStrategy = new Hscan("balls");
+ int iterationCount = 2;
+ RedisIterator iterator = redisClient.iterator(iterationCount, "*", scanStrategy);
+ List> results = new LinkedList>();
+ while (iterator.hasNext()) {
+ results.addAll(iterator.next());
+ }
+ Assert.assertEquals(hash.size(), results.size());
+ }
+
+ @Test
+ public void testZscanStrategy() {
+ HashMap memberScores = new HashMap();
+ memberScores.put("cricket", (double) 160);
+ memberScores.put("football", (double) 450);
+ memberScores.put("volleyball", (double) 270);
+ redisClient.zadd("balls", memberScores);
+
+ Zscan scanStrategy = new Zscan("balls");
+ int iterationCount = 2;
+ RedisIterator iterator = redisClient.iterator(iterationCount, "*", scanStrategy);
+ List results = new LinkedList();
+ while (iterator.hasNext()) {
+ results.addAll(iterator.next());
+ }
+ Assert.assertEquals(memberScores.size(), results.size());
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index aeaef5f676..e641aebe7d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -485,6 +485,7 @@
jooby
jsf
json
+ json-2
json-path
jsoup
jta