Skip to content

Commit

Permalink
Merge pull request #34 from tharakamd/sentinel
Browse files Browse the repository at this point in the history
Add Redis Sentinel Implementation
  • Loading branch information
tharakamd authored Sep 1, 2021
2 parents 102fb60 + b0c94e8 commit 8e5d6b6
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 3 deletions.
16 changes: 15 additions & 1 deletion docs/configuringRedisOperations.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ If you prefer to use the connectionURI over above configuration, use the followi
</redis.init>
```

**Redis Sentinel**
```xml
<redis.init>
<sentinelEnabled>true</sentinelEnabled>
<masterName>{$ctx:masterName}</masterName>
<sentinels>{$ctx:sentinels}</sentinels>
<masterPassword>{$ctx:masterPassword}</masterPassword>
<dbNumber>{$ctx:dbNumber}</dbNumber>
</redis.init>
```
**Properties**
* redisClusterEnabled: A flag to enable the redis cluster mode (Default is false).
* clusterNodes: Comma separated list of the cluster nodes as Node1_hostname:Port,Node2_hostname:Port, etc.
Expand All @@ -61,7 +71,11 @@ If you prefer to use the connectionURI over above configuration, use the followi
* maxAttempts: The number of retries.
* redisConnectionURI: The Redis connection URI in the form of `redis://[user:password@]host[:port]/[database]` or
`rediss://[user:password@]host[:port]/[database]` to connect over TLS/SSL

* sentinelEnabled: A flag to enable sentinel
* masterName: Master name in sentinel mode
* sentinels: Comma separated list of sentinels
* masterPassword: Master password (don't specify if there's no password for master)
* dbNumber: Number of the DB (integer)

Now that you have connected to Redis, use the information in the following topics to perform various operations with the connector:

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<groupId>org.wso2.carbon.connector</groupId>
<artifactId>org.wso2.carbon.connector.redis</artifactId>
<packaging>jar</packaging>
<version>2.2.0</version>
<version>2.3.0-SNAPSHOT</version>
<name>WSO2 Carbon - Mediation Library Connector For Redis</name>
<url>http://wso2.org</url>
<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.JedisShardInfo;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;

import static redis.clients.jedis.Protocol.DEFAULT_DATABASE;

public class RedisServer {

private Jedis jedis;
Expand All @@ -43,6 +47,11 @@ public class RedisServer {
private int connectionTimeout;
private boolean useSsl = false;
private String cacheKey = null;
private boolean isSentinelEnabled = false;
private String masterName;
private java.util.Set<String> sentinels;
private String masterPassword;
private int dbNumber = DEFAULT_DATABASE;

public RedisServer(MessageContext messageContext) {
this.messageContext = messageContext;
Expand All @@ -56,6 +65,11 @@ public RedisServer(MessageContext messageContext) {
String cacheKeyProp = (String) messageContext.getProperty(RedisConstants.CACHEKEY);
String sslProp = (String) messageContext.getProperty(RedisConstants.USESSL);

String sentinelEnabled = (String) messageContext.getProperty(RedisConstants.SENTINEL_ENABLED);
if (sentinelEnabled != null && !sentinelEnabled.isEmpty()) {
isSentinelEnabled = Boolean.parseBoolean(sentinelEnabled);
}

if (soTimeoutProp != null && !soTimeoutProp.isEmpty()) {
try {
timeout = Integer.parseInt(soTimeoutProp);
Expand Down Expand Up @@ -92,6 +106,12 @@ public RedisServer(MessageContext messageContext) {
* @return Jedis instance
*/
private Jedis createJedis() {

if (isSentinelEnabled) {

return createSentinel();
}

String connectionURIProp = (String) messageContext.getProperty(RedisConstants.CONNECTION_URI);
if (connectionURIProp != null) {
try {
Expand Down Expand Up @@ -140,6 +160,44 @@ private Jedis createJedis() {
return new Jedis(host, port, connectionTimeout, timeout, useSsl);
}

private Jedis createSentinel() {

String masterNameProp = (String) messageContext.getProperty(RedisConstants.MASTER_NAME);
if (masterNameProp != null && !masterNameProp.isEmpty()) {
masterName = masterNameProp;
} else{
throw new SynapseException("Value for \"masterName\" cannot be empty in sentinel");
}

String sentinelsProp = (String) messageContext.getProperty(RedisConstants.SENTINELS);
if (sentinelsProp != null && !sentinelsProp.isEmpty()) {
sentinels = new HashSet<>(Arrays.asList(sentinelsProp.split(",")));
} else {
throw new SynapseException("Value for \"sentinels\" cannot be empty in sentinel");

}

String dbNumberProp = (String) messageContext.getProperty(RedisConstants.DB_NUMBER);
if (dbNumberProp != null && !dbNumberProp.isEmpty()) {
try {
dbNumber = Integer.parseInt(dbNumberProp);
} catch (NumberFormatException e) {
throw new SynapseException(
"Invalid input for \"dbNumber\". Cannot parse " + dbNumberProp + " to an Integer.", e);
}
}

String masterPasswordProp = (String) messageContext.getProperty(RedisConstants.MASTER_PASSWORD);
if (masterPasswordProp != null && !masterPasswordProp.isEmpty()) {
masterPassword = masterPasswordProp;
}

try (JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels,
new GenericObjectPoolConfig(), connectionTimeout, timeout, masterPassword, dbNumber)) {
return jedisSentinelPool.getResource();
}
}

/**
* Create a JedisCluster instance according to the parameters given.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,10 @@ public class RedisConstants {
public static final int DEFAULT_TIMEOUT = 2000;
public static final int DEFAULT_MAX_ATTEMPTS = 5;
public static final int DEFAULT_WEIGHT = 1;

public static final String SENTINEL_ENABLED = "sentinelEnabled";
public static final String MASTER_NAME = "masterName";
public static final String SENTINELS = "sentinels";
public static final String MASTER_PASSWORD = "masterPassword";
public static final String DB_NUMBER = "dbNumber";
}
37 changes: 37 additions & 0 deletions src/main/resources/config/init.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
<parameter name="clusterNodes" description="comma separated list of the cluster nodes (host:port)"/>
<parameter name="clientName" description="name of the client"/>
<parameter name="maxAttempts" description="the number of retries"/>

<!-- Redis Sentinel specific parameters-->
<parameter name="sentinelEnabled" description="a flag to enable redis sentinel"/>
<parameter name="masterName" description="master name for sentinel"/>
<parameter name="sentinels" description="comma separated list of sentinels"/>
<parameter name="masterPassword" description="master password"/>
<parameter name="dbNumber" description="dbNumber"/>

<sequence>
<filter xpath="$func:redisPort = '' or not(string($func:redisPort))">
Expand Down Expand Up @@ -107,6 +114,36 @@
<else>
<property name="redisConnectionURI" expression="$func:redisConnectionURI"/>
</else>
</filter>
<filter xpath="$func:sentinelEnabled = '' or not(string($func:sentinelEnabled))">
<then/>
<else>
<property name="sentinelEnabled" expression="$func:sentinelEnabled"/>
</else>
</filter>
<filter xpath="$func:masterName = '' or not(string($func:masterName))">
<then/>
<else>
<property name="masterName" expression="$func:masterName"/>
</else>
</filter>
<filter xpath="$func:sentinels = '' or not(string($func:sentinels))">
<then/>
<else>
<property name="sentinels" expression="$func:sentinels"/>
</else>
</filter>
<filter xpath="$func:masterPassword = '' or not(string($func:masterPassword))">
<then/>
<else>
<property name="masterPassword" expression="$func:masterPassword"/>
</else>
</filter>
<filter xpath="$func:dbNumber = '' or not(string($func:dbNumber))">
<then/>
<else>
<property name="dbNumber" expression="$func:dbNumber"/>
</else>
</filter>
</sequence>
</template>
2 changes: 1 addition & 1 deletion src/main/resources/strings/get.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
}
</format>
<args>
<arg evaluator="xml" expression="$ctx:redisResponse"/>
<arg evaluator="xml" expression="$ctx:redisResponse" literal="true"/>
</args>
</payloadFactory>
</sequence>
Expand Down

0 comments on commit 8e5d6b6

Please sign in to comment.