Fixed - host name containing underscore cause NPE. Illegal reflective access by org.redisson.misc.URIBuilder warning removed #2150 #2029

pull/2160/head^2
Nikita Koksharov 6 years ago
parent b2fc908615
commit 0ce487f08d

@ -15,7 +15,6 @@
*/ */
package org.redisson; package org.redisson;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -37,7 +36,7 @@ import org.redisson.connection.ConnectionListener;
import org.redisson.connection.ConnectionManager; import org.redisson.connection.ConnectionManager;
import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.MasterSlaveEntry;
import org.redisson.connection.RedisClientEntry; import org.redisson.connection.RedisClientEntry;
import org.redisson.misc.URIBuilder; import org.redisson.misc.RedisURI;
/** /**
* *
@ -56,15 +55,15 @@ public class RedisNodes<N extends Node> implements NodesGroup<N> {
@Override @Override
public N getNode(String address) { public N getNode(String address) {
Collection<MasterSlaveEntry> entries = connectionManager.getEntrySet(); Collection<MasterSlaveEntry> entries = connectionManager.getEntrySet();
URI addr = URIBuilder.create(address); RedisURI addr = new RedisURI(address);
for (MasterSlaveEntry masterSlaveEntry : entries) { for (MasterSlaveEntry masterSlaveEntry : entries) {
if (masterSlaveEntry.getAllEntries().isEmpty() if (masterSlaveEntry.getAllEntries().isEmpty()
&& URIBuilder.compare(masterSlaveEntry.getClient().getAddr(), addr)) { && RedisURI.compare(masterSlaveEntry.getClient().getAddr(), addr)) {
return (N) new RedisClientEntry(masterSlaveEntry.getClient(), connectionManager.getCommandExecutor(), NodeType.MASTER); return (N) new RedisClientEntry(masterSlaveEntry.getClient(), connectionManager.getCommandExecutor(), NodeType.MASTER);
} }
for (ClientConnectionsEntry entry : masterSlaveEntry.getAllEntries()) { for (ClientConnectionsEntry entry : masterSlaveEntry.getAllEntries()) {
if (URIBuilder.compare(entry.getClient().getAddr(), addr) if (RedisURI.compare(entry.getClient().getAddr(), addr)
&& entry.getFreezeReason() != FreezeReason.MANAGER) { && entry.getFreezeReason() != FreezeReason.MANAGER) {
return (N) new RedisClientEntry(entry.getClient(), connectionManager.getCommandExecutor(), entry.getNodeType()); return (N) new RedisClientEntry(entry.getClient(), connectionManager.getCommandExecutor(), entry.getNodeType());
} }

@ -17,7 +17,6 @@ package org.redisson.client;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -28,6 +27,7 @@ import org.redisson.api.RFuture;
import org.redisson.client.handler.RedisChannelInitializer; import org.redisson.client.handler.RedisChannelInitializer;
import org.redisson.client.handler.RedisChannelInitializer.Type; import org.redisson.client.handler.RedisChannelInitializer.Type;
import org.redisson.misc.RPromise; import org.redisson.misc.RPromise;
import org.redisson.misc.RedisURI;
import org.redisson.misc.RedissonPromise; import org.redisson.misc.RedissonPromise;
import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.Bootstrap;
@ -63,7 +63,7 @@ public final class RedisClient {
private final AtomicReference<RFuture<InetSocketAddress>> resolvedAddrFuture = new AtomicReference<RFuture<InetSocketAddress>>(); private final AtomicReference<RFuture<InetSocketAddress>> resolvedAddrFuture = new AtomicReference<RFuture<InetSocketAddress>>();
private final Bootstrap bootstrap; private final Bootstrap bootstrap;
private final Bootstrap pubSubBootstrap; private final Bootstrap pubSubBootstrap;
private final URI uri; private final RedisURI uri;
private InetSocketAddress resolvedAddr; private InetSocketAddress resolvedAddr;
private final ChannelGroup channels; private final ChannelGroup channels;

@ -20,7 +20,7 @@ import java.net.URI;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import org.redisson.config.SslProvider; import org.redisson.config.SslProvider;
import org.redisson.misc.URIBuilder; import org.redisson.misc.RedisURI;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
@ -35,7 +35,7 @@ import io.netty.util.Timer;
*/ */
public class RedisClientConfig { public class RedisClientConfig {
private URI address; private RedisURI address;
private InetSocketAddress addr; private InetSocketAddress addr;
private Timer timer; private Timer timer;
@ -105,23 +105,23 @@ public class RedisClientConfig {
} }
public RedisClientConfig setAddress(String host, int port) { public RedisClientConfig setAddress(String host, int port) {
this.address = URIBuilder.create("redis://" + host + ":" + port); this.address = new RedisURI("redis://" + host + ":" + port);
return this; return this;
} }
public RedisClientConfig setAddress(String address) { public RedisClientConfig setAddress(String address) {
this.address = URIBuilder.create(address); this.address = new RedisURI(address);
return this; return this;
} }
public RedisClientConfig setAddress(InetSocketAddress addr, URI address) { public RedisClientConfig setAddress(InetSocketAddress addr, RedisURI address) {
this.addr = addr; this.addr = addr;
this.address = address; this.address = address;
return this; return this;
} }
public RedisClientConfig setAddress(URI address) { public RedisClientConfig setAddress(RedisURI address) {
this.address = address; this.address = address;
return this; return this;
} }
public URI getAddress() { public RedisURI getAddress() {
return address; return address;
} }
public InetSocketAddress getAddr() { public InetSocketAddress getAddr() {

@ -15,9 +15,7 @@
*/ */
package org.redisson.client; package org.redisson.client;
import java.net.URI; import org.redisson.misc.RedisURI;
import org.redisson.misc.URIBuilder;
/** /**
* *
@ -29,18 +27,18 @@ public class RedisRedirectException extends RedisException {
private static final long serialVersionUID = 181505625075250011L; private static final long serialVersionUID = 181505625075250011L;
private final int slot; private final int slot;
private final URI url; private final RedisURI url;
public RedisRedirectException(int slot, String url) { public RedisRedirectException(int slot, String url) {
this.slot = slot; this.slot = slot;
this.url = URIBuilder.create("redis://" + url); this.url = new RedisURI("redis://" + url);
} }
public int getSlot() { public int getSlot() {
return slot; return slot;
} }
public URI getUrl() { public RedisURI getUrl() {
return url; return url;
} }

@ -16,7 +16,6 @@
package org.redisson.cluster; package org.redisson.cluster;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.BitSet; import java.util.BitSet;
@ -36,6 +35,7 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.redisson.api.NodeType; import org.redisson.api.NodeType;
import org.redisson.api.RFuture; import org.redisson.api.RFuture;
@ -58,8 +58,8 @@ import org.redisson.connection.MasterSlaveConnectionManager;
import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.MasterSlaveEntry;
import org.redisson.connection.SingleEntry; import org.redisson.connection.SingleEntry;
import org.redisson.misc.RPromise; import org.redisson.misc.RPromise;
import org.redisson.misc.RedisURI;
import org.redisson.misc.RedissonPromise; import org.redisson.misc.RedissonPromise;
import org.redisson.misc.URIBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -82,7 +82,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
private ScheduledFuture<?> monitorFuture; private ScheduledFuture<?> monitorFuture;
private volatile URI lastClusterNode; private volatile RedisURI lastClusterNode;
private RedisStrictCommand<List<ClusterNodeInfo>> clusterNodesCommand; private RedisStrictCommand<List<ClusterNodeInfo>> clusterNodesCommand;
@ -103,7 +103,8 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
Throwable lastException = null; Throwable lastException = null;
List<String> failedMasters = new ArrayList<String>(); List<String> failedMasters = new ArrayList<String>();
for (URI addr : cfg.getNodeAddresses()) { for (String address : cfg.getNodeAddresses()) {
RedisURI addr = new RedisURI(address);
RFuture<RedisConnection> connectionFuture = connectToNode(cfg, addr, null, addr.getHost()); RFuture<RedisConnection> connectionFuture = connectToNode(cfg, addr, null, addr.getHost());
try { try {
RedisConnection connection = connectionFuture.syncUninterruptibly().getNow(); RedisConnection connection = connectionFuture.syncUninterruptibly().getNow();
@ -180,7 +181,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
} }
@Override @Override
protected RedisClientConfig createRedisConfig(NodeType type, URI address, int timeout, int commandTimeout, String sslHostname) { protected RedisClientConfig createRedisConfig(NodeType type, RedisURI address, int timeout, int commandTimeout, String sslHostname) {
RedisClientConfig result = super.createRedisConfig(type, address, timeout, commandTimeout, sslHostname); RedisClientConfig result = super.createRedisConfig(type, address, timeout, commandTimeout, sslHostname);
result.setReadOnly(type == NodeType.SLAVE && config.getReadMode() != ReadMode.MASTER); result.setReadOnly(type == NodeType.SLAVE && config.getReadMode() != ReadMode.MASTER);
return result; return result;
@ -226,14 +227,15 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
} }
MasterSlaveServersConfig config = create(cfg); MasterSlaveServersConfig config = create(cfg);
config.setMasterAddress(partition.getMasterAddress()); config.setMasterAddress(partition.getMasterAddress().toString());
MasterSlaveEntry e; MasterSlaveEntry e;
List<RFuture<Void>> futures = new ArrayList<RFuture<Void>>(); List<RFuture<Void>> futures = new ArrayList<RFuture<Void>>();
if (config.checkSkipSlavesInit()) { if (config.checkSkipSlavesInit()) {
e = new SingleEntry(ClusterConnectionManager.this, config); e = new SingleEntry(ClusterConnectionManager.this, config);
} else { } else {
config.setSlaveAddresses(partition.getSlaveAddresses()); Set<String> slaveAddresses = partition.getSlaveAddresses().stream().map(r -> r.toString()).collect(Collectors.toSet());
config.setSlaveAddresses(slaveAddresses);
e = new MasterSlaveEntry(ClusterConnectionManager.this, config); e = new MasterSlaveEntry(ClusterConnectionManager.this, config);
@ -247,7 +249,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
} }
} }
RFuture<RedisClient> f = e.setupMasterEntry(config.getMasterAddress()); RFuture<RedisClient> f = e.setupMasterEntry(new RedisURI(config.getMasterAddress()));
RPromise<Void> initFuture = new RedissonPromise<Void>(); RPromise<Void> initFuture = new RedissonPromise<Void>();
futures.add(initFuture); futures.add(initFuture);
f.onComplete((res, ex3) -> { f.onComplete((res, ex3) -> {
@ -275,12 +277,13 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
return result; return result;
} }
private void scheduleClusterChangeCheck(ClusterServersConfig cfg, Iterator<URI> iterator) { private void scheduleClusterChangeCheck(ClusterServersConfig cfg, Iterator<RedisURI> iterator) {
monitorFuture = group.schedule(new Runnable() { monitorFuture = group.schedule(new Runnable() {
@Override @Override
public void run() { public void run() {
if (configEndpointHostName != null) { if (configEndpointHostName != null) {
URI uri = cfg.getNodeAddresses().iterator().next(); String address = cfg.getNodeAddresses().iterator().next();
RedisURI uri = new RedisURI(address);
AddressResolver<InetSocketAddress> resolver = resolverGroup.getResolver(getGroup().next()); AddressResolver<InetSocketAddress> resolver = resolverGroup.getResolver(getGroup().next());
Future<List<InetSocketAddress>> allNodes = resolver.resolveAll(InetSocketAddress.createUnresolved(uri.getHost(), uri.getPort())); Future<List<InetSocketAddress>> allNodes = resolver.resolveAll(InetSocketAddress.createUnresolved(uri.getHost(), uri.getPort()));
allNodes.addListener(new FutureListener<List<InetSocketAddress>>() { allNodes.addListener(new FutureListener<List<InetSocketAddress>>() {
@ -288,34 +291,34 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
public void operationComplete(Future<List<InetSocketAddress>> future) throws Exception { public void operationComplete(Future<List<InetSocketAddress>> future) throws Exception {
AtomicReference<Throwable> lastException = new AtomicReference<Throwable>(future.cause()); AtomicReference<Throwable> lastException = new AtomicReference<Throwable>(future.cause());
if (!future.isSuccess()) { if (!future.isSuccess()) {
checkClusterState(cfg, Collections.<URI>emptyList().iterator(), lastException); checkClusterState(cfg, Collections.<RedisURI>emptyList().iterator(), lastException);
return; return;
} }
List<URI> nodes = new ArrayList<URI>(); List<RedisURI> nodes = new ArrayList<>();
for (InetSocketAddress addr : future.getNow()) { for (InetSocketAddress addr : future.getNow()) {
URI node = URIBuilder.create(uri.getScheme() + "://" + addr.getAddress().getHostAddress() + ":" + addr.getPort()); RedisURI node = new RedisURI(uri.getScheme() + "://" + addr.getAddress().getHostAddress() + ":" + addr.getPort());
URI address = applyNatMap(node); RedisURI address = applyNatMap(node);
nodes.add(address); nodes.add(address);
} }
Iterator<URI> nodesIterator = nodes.iterator(); Iterator<RedisURI> nodesIterator = nodes.iterator();
checkClusterState(cfg, nodesIterator, lastException); checkClusterState(cfg, nodesIterator, lastException);
} }
}); });
} else { } else {
AtomicReference<Throwable> lastException = new AtomicReference<Throwable>(); AtomicReference<Throwable> lastException = new AtomicReference<Throwable>();
Iterator<URI> nodesIterator = iterator; Iterator<RedisURI> nodesIterator = iterator;
if (nodesIterator == null) { if (nodesIterator == null) {
List<URI> nodes = new ArrayList<URI>(); List<RedisURI> nodes = new ArrayList<>();
List<URI> slaves = new ArrayList<URI>(); List<RedisURI> slaves = new ArrayList<>();
for (ClusterPartition partition : getLastPartitions()) { for (ClusterPartition partition : getLastPartitions()) {
if (!partition.isMasterFail()) { if (!partition.isMasterFail()) {
nodes.add(partition.getMasterAddress()); nodes.add(partition.getMasterAddress());
} }
Set<URI> partitionSlaves = new HashSet<URI>(partition.getSlaveAddresses()); Set<RedisURI> partitionSlaves = new HashSet<>(partition.getSlaveAddresses());
partitionSlaves.removeAll(partition.getFailedSlaveAddresses()); partitionSlaves.removeAll(partition.getFailedSlaveAddresses());
slaves.addAll(partitionSlaves); slaves.addAll(partitionSlaves);
} }
@ -332,7 +335,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
}, cfg.getScanInterval(), TimeUnit.MILLISECONDS); }, cfg.getScanInterval(), TimeUnit.MILLISECONDS);
} }
private void checkClusterState(ClusterServersConfig cfg, Iterator<URI> iterator, AtomicReference<Throwable> lastException) { private void checkClusterState(ClusterServersConfig cfg, Iterator<RedisURI> iterator, AtomicReference<Throwable> lastException) {
if (!iterator.hasNext()) { if (!iterator.hasNext()) {
if (lastException.get() != null) { if (lastException.get() != null) {
log.error("Can't update cluster state", lastException.get()); log.error("Can't update cluster state", lastException.get());
@ -343,7 +346,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
if (!getShutdownLatch().acquire()) { if (!getShutdownLatch().acquire()) {
return; return;
} }
URI uri = iterator.next(); RedisURI uri = iterator.next();
RFuture<RedisConnection> connectionFuture = connectToNode(cfg, uri, null, configEndpointHostName); RFuture<RedisConnection> connectionFuture = connectToNode(cfg, uri, null, configEndpointHostName);
connectionFuture.onComplete((connection, e) -> { connectionFuture.onComplete((connection, e) -> {
if (e != null) { if (e != null) {
@ -358,7 +361,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
} }
private void updateClusterState(ClusterServersConfig cfg, RedisConnection connection, private void updateClusterState(ClusterServersConfig cfg, RedisConnection connection,
Iterator<URI> iterator, URI uri, AtomicReference<Throwable> lastException) { Iterator<RedisURI> iterator, RedisURI uri, AtomicReference<Throwable> lastException) {
RFuture<List<ClusterNodeInfo>> future = connection.async(clusterNodesCommand); RFuture<List<ClusterNodeInfo>> future = connection.async(clusterNodesCommand);
future.onComplete((nodes, e) -> { future.onComplete((nodes, e) -> {
if (e != null) { if (e != null) {
@ -402,7 +405,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
MasterSlaveEntry entry = getEntry(currentPart.slots().nextSetBit(0)); MasterSlaveEntry entry = getEntry(currentPart.slots().nextSetBit(0));
// should be invoked first in order to remove stale failedSlaveAddresses // should be invoked first in order to remove stale failedSlaveAddresses
Set<URI> addedSlaves = addRemoveSlaves(entry, currentPart, newPart); Set<RedisURI> addedSlaves = addRemoveSlaves(entry, currentPart, newPart);
// Do some slaves have changed state from failed to alive? // Do some slaves have changed state from failed to alive?
upDownSlaves(entry, currentPart, newPart, addedSlaves); upDownSlaves(entry, currentPart, newPart, addedSlaves);
@ -411,20 +414,20 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
} }
} }
private void upDownSlaves(MasterSlaveEntry entry, ClusterPartition currentPart, ClusterPartition newPart, Set<URI> addedSlaves) { private void upDownSlaves(MasterSlaveEntry entry, ClusterPartition currentPart, ClusterPartition newPart, Set<RedisURI> addedSlaves) {
Set<URI> aliveSlaves = new HashSet<URI>(currentPart.getFailedSlaveAddresses()); Set<RedisURI> aliveSlaves = new HashSet<>(currentPart.getFailedSlaveAddresses());
aliveSlaves.removeAll(addedSlaves); aliveSlaves.removeAll(addedSlaves);
aliveSlaves.removeAll(newPart.getFailedSlaveAddresses()); aliveSlaves.removeAll(newPart.getFailedSlaveAddresses());
for (URI uri : aliveSlaves) { for (RedisURI uri : aliveSlaves) {
currentPart.removeFailedSlaveAddress(uri); currentPart.removeFailedSlaveAddress(uri);
if (entry.hasSlave(uri) && entry.slaveUp(uri, FreezeReason.MANAGER)) { if (entry.hasSlave(uri) && entry.slaveUp(uri, FreezeReason.MANAGER)) {
log.info("slave: {} has up for slot ranges: {}", uri, currentPart.getSlotRanges()); log.info("slave: {} has up for slot ranges: {}", uri, currentPart.getSlotRanges());
} }
} }
Set<URI> failedSlaves = new HashSet<URI>(newPart.getFailedSlaveAddresses()); Set<RedisURI> failedSlaves = new HashSet<>(newPart.getFailedSlaveAddresses());
failedSlaves.removeAll(currentPart.getFailedSlaveAddresses()); failedSlaves.removeAll(currentPart.getFailedSlaveAddresses());
for (URI uri : failedSlaves) { for (RedisURI uri : failedSlaves) {
currentPart.addFailedSlaveAddress(uri); currentPart.addFailedSlaveAddress(uri);
if (entry.slaveDown(uri, FreezeReason.MANAGER)) { if (entry.slaveDown(uri, FreezeReason.MANAGER)) {
log.warn("slave: {} has down for slot ranges: {}", uri, currentPart.getSlotRanges()); log.warn("slave: {} has down for slot ranges: {}", uri, currentPart.getSlotRanges());
@ -432,11 +435,11 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
} }
} }
private Set<URI> addRemoveSlaves(MasterSlaveEntry entry, ClusterPartition currentPart, ClusterPartition newPart) { private Set<RedisURI> addRemoveSlaves(MasterSlaveEntry entry, ClusterPartition currentPart, ClusterPartition newPart) {
Set<URI> removedSlaves = new HashSet<URI>(currentPart.getSlaveAddresses()); Set<RedisURI> removedSlaves = new HashSet<>(currentPart.getSlaveAddresses());
removedSlaves.removeAll(newPart.getSlaveAddresses()); removedSlaves.removeAll(newPart.getSlaveAddresses());
for (URI uri : removedSlaves) { for (RedisURI uri : removedSlaves) {
currentPart.removeSlaveAddress(uri); currentPart.removeSlaveAddress(uri);
if (entry.slaveDown(uri, FreezeReason.MANAGER)) { if (entry.slaveDown(uri, FreezeReason.MANAGER)) {
@ -444,9 +447,9 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
} }
} }
Set<URI> addedSlaves = new HashSet<URI>(newPart.getSlaveAddresses()); Set<RedisURI> addedSlaves = new HashSet<>(newPart.getSlaveAddresses());
addedSlaves.removeAll(currentPart.getSlaveAddresses()); addedSlaves.removeAll(currentPart.getSlaveAddresses());
for (URI uri : addedSlaves) { for (RedisURI uri : addedSlaves) {
RFuture<Void> future = entry.addSlave(uri); RFuture<Void> future = entry.addSlave(uri);
future.onComplete((res, ex) -> { future.onComplete((res, ex) -> {
if (ex != null) { if (ex != null) {
@ -499,8 +502,8 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
ClusterPartition newMasterPart = find(newPartitions, slot); ClusterPartition newMasterPart = find(newPartitions, slot);
// does partition has a new master? // does partition has a new master?
if (!newMasterPart.getMasterAddress().equals(currentPart.getMasterAddress())) { if (!newMasterPart.getMasterAddress().equals(currentPart.getMasterAddress())) {
URI newUri = newMasterPart.getMasterAddress(); RedisURI newUri = newMasterPart.getMasterAddress();
URI oldUri = currentPart.getMasterAddress(); RedisURI oldUri = currentPart.getMasterAddress();
RFuture<RedisClient> future = changeMaster(slot, newUri); RFuture<RedisClient> future = changeMaster(slot, newUri);
future.onComplete((res, e) -> { future.onComplete((res, e) -> {
@ -693,10 +696,10 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
return result; return result;
} }
public URI applyNatMap(URI address) { public RedisURI applyNatMap(RedisURI address) {
String mappedAddress = natMap.get(address.getHost() + ":" + address.getPort()); String mappedAddress = natMap.get(address.getHost() + ":" + address.getPort());
if (mappedAddress != null) { if (mappedAddress != null) {
return URIBuilder.create(address.getScheme() + "://" + mappedAddress); return new RedisURI(address.getScheme() + "://" + mappedAddress);
} }
return address; return address;
} }
@ -718,7 +721,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
ClusterPartition partition = getPartition(partitions, id); ClusterPartition partition = getPartition(partitions, id);
URI address = applyNatMap(clusterNodeInfo.getAddress()); RedisURI address = applyNatMap(clusterNodeInfo.getAddress());
if (clusterNodeInfo.containsFlag(Flag.SLAVE)) { if (clusterNodeInfo.containsFlag(Flag.SLAVE)) {
slavePartition.setParent(partition); slavePartition.setParent(partition);
@ -751,10 +754,10 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
if (cp.getParent() != null && cp.getParent().getType() == Type.MASTER) { if (cp.getParent() != null && cp.getParent().getType() == Type.MASTER) {
ClusterPartition parent = cp.getParent(); ClusterPartition parent = cp.getParent();
for (URI addr : cp.getSlaveAddresses()) { for (RedisURI addr : cp.getSlaveAddresses()) {
parent.addSlaveAddress(addr); parent.addSlaveAddress(addr);
} }
for (URI addr : cp.getFailedSlaveAddresses()) { for (RedisURI addr : cp.getFailedSlaveAddresses()) {
parent.addFailedSlaveAddress(addr); parent.addFailedSlaveAddress(addr);
} }
} }
@ -787,7 +790,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
} }
@Override @Override
public URI getLastClusterNode() { public RedisURI getLastClusterNode() {
return lastClusterNode; return lastClusterNode;
} }

@ -15,11 +15,11 @@
*/ */
package org.redisson.cluster; package org.redisson.cluster;
import java.net.URI;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.redisson.misc.URIBuilder;
import org.redisson.misc.RedisURI;
/** /**
* *
@ -33,7 +33,7 @@ public class ClusterNodeInfo {
private final String nodeInfo; private final String nodeInfo;
private String nodeId; private String nodeId;
private URI address; private RedisURI address;
private final Set<Flag> flags = EnumSet.noneOf(Flag.class); private final Set<Flag> flags = EnumSet.noneOf(Flag.class);
private String slaveOf; private String slaveOf;
@ -50,11 +50,11 @@ public class ClusterNodeInfo {
this.nodeId = nodeId; this.nodeId = nodeId;
} }
public URI getAddress() { public RedisURI getAddress() {
return address; return address;
} }
public void setAddress(String address) { public void setAddress(String address) {
this.address = URIBuilder.create(address); this.address = new RedisURI(address);
} }
public void addSlotRange(ClusterSlotRange range) { public void addSlotRange(ClusterSlotRange range) {

@ -15,12 +15,13 @@
*/ */
package org.redisson.cluster; package org.redisson.cluster;
import java.net.URI;
import java.util.BitSet; import java.util.BitSet;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.redisson.misc.RedisURI;
/** /**
* *
* @author Nikita Koksharov * @author Nikita Koksharov
@ -34,9 +35,9 @@ public class ClusterPartition {
private final String nodeId; private final String nodeId;
private boolean masterFail; private boolean masterFail;
private URI masterAddress; private RedisURI masterAddress;
private final Set<URI> slaveAddresses = new HashSet<URI>(); private final Set<RedisURI> slaveAddresses = new HashSet<>();
private final Set<URI> failedSlaves = new HashSet<URI>(); private final Set<RedisURI> failedSlaves = new HashSet<>();
private final BitSet slots = new BitSet(); private final BitSet slots = new BitSet();
private final Set<ClusterSlotRange> slotRanges = new HashSet<ClusterSlotRange>(); private final Set<ClusterSlotRange> slotRanges = new HashSet<ClusterSlotRange>();
@ -123,30 +124,30 @@ public class ClusterPartition {
return slots.cardinality(); return slots.cardinality();
} }
public URI getMasterAddress() { public RedisURI getMasterAddress() {
return masterAddress; return masterAddress;
} }
public void setMasterAddress(URI masterAddress) { public void setMasterAddress(RedisURI masterAddress) {
this.masterAddress = masterAddress; this.masterAddress = masterAddress;
} }
public void addFailedSlaveAddress(URI address) { public void addFailedSlaveAddress(RedisURI address) {
failedSlaves.add(address); failedSlaves.add(address);
} }
public Set<URI> getFailedSlaveAddresses() { public Set<RedisURI> getFailedSlaveAddresses() {
return Collections.unmodifiableSet(failedSlaves); return Collections.unmodifiableSet(failedSlaves);
} }
public void removeFailedSlaveAddress(URI uri) { public void removeFailedSlaveAddress(RedisURI uri) {
failedSlaves.remove(uri); failedSlaves.remove(uri);
} }
public void addSlaveAddress(URI address) { public void addSlaveAddress(RedisURI address) {
slaveAddresses.add(address); slaveAddresses.add(address);
} }
public Set<URI> getSlaveAddresses() { public Set<RedisURI> getSlaveAddresses() {
return Collections.unmodifiableSet(slaveAddresses); return Collections.unmodifiableSet(slaveAddresses);
} }
public void removeSlaveAddress(URI uri) { public void removeSlaveAddress(RedisURI uri) {
slaveAddresses.remove(uri); slaveAddresses.remove(uri);
failedSlaves.remove(uri); failedSlaves.remove(uri);
} }

@ -15,15 +15,13 @@
*/ */
package org.redisson.config; package org.redisson.config;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.redisson.misc.URIBuilder;
/** /**
* *
* @author Nikita Koksharov * @author Nikita Koksharov
@ -36,7 +34,7 @@ public class ClusterServersConfig extends BaseMasterSlaveServersConfig<ClusterSe
/** /**
* Redis cluster node urls list * Redis cluster node urls list
*/ */
private List<URI> nodeAddresses = new ArrayList<URI>(); private List<String> nodeAddresses = new ArrayList<>();
/** /**
* Redis cluster scan interval in milliseconds * Redis cluster scan interval in milliseconds
@ -60,15 +58,13 @@ public class ClusterServersConfig extends BaseMasterSlaveServersConfig<ClusterSe
* @return config * @return config
*/ */
public ClusterServersConfig addNodeAddress(String... addresses) { public ClusterServersConfig addNodeAddress(String... addresses) {
for (String address : addresses) { nodeAddresses.addAll(Arrays.asList(addresses));
nodeAddresses.add(URIBuilder.create(address));
}
return this; return this;
} }
public List<URI> getNodeAddresses() { public List<String> getNodeAddresses() {
return nodeAddresses; return nodeAddresses;
} }
void setNodeAddresses(List<URI> nodeAddresses) { void setNodeAddresses(List<String> nodeAddresses) {
this.nodeAddresses = nodeAddresses; this.nodeAddresses = nodeAddresses;
} }

@ -28,7 +28,6 @@ import org.redisson.connection.AddressResolverGroupFactory;
import org.redisson.connection.ConnectionManager; import org.redisson.connection.ConnectionManager;
import org.redisson.connection.DnsAddressResolverGroupFactory; import org.redisson.connection.DnsAddressResolverGroupFactory;
import org.redisson.connection.ReplicatedConnectionManager; import org.redisson.connection.ReplicatedConnectionManager;
import org.redisson.misc.URIBuilder;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
@ -95,10 +94,6 @@ public class Config {
public Config() { public Config() {
} }
static {
URIBuilder.patchUriObject();
}
public Config(Config oldConf) { public Config(Config oldConf) {
setExecutor(oldConf.getExecutor()); setExecutor(oldConf.getExecutor());

@ -21,9 +21,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.net.URI;
import java.net.URL; import java.net.URL;
import java.util.List;
import java.util.Scanner; import java.util.Scanner;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -42,7 +40,6 @@ import org.redisson.connection.SingleConnectionManager;
import org.redisson.connection.balancer.LoadBalancer; import org.redisson.connection.balancer.LoadBalancer;
import com.fasterxml.jackson.annotation.JsonFilter; import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
@ -68,38 +65,6 @@ public class ConfigSupport {
} }
public abstract static class SingleSeverConfigMixIn {
@JsonProperty
List<URI> address;
@JsonIgnore
abstract SingleServerConfig setAddress(String address);
@JsonIgnore
abstract URI getAddress();
@JsonIgnore
abstract void setAddress(URI address);
}
public abstract static class MasterSlaveServersConfigMixIn {
@JsonProperty
List<URI> masterAddress;
@JsonIgnore
abstract MasterSlaveServersConfig setMasterAddress(String masterAddress);
@JsonIgnore
abstract URI getMasterAddress();
@JsonIgnore
abstract void setMasterAddress(URI masterAddress);
}
@JsonIgnoreProperties({"clusterConfig", "sentinelConfig"}) @JsonIgnoreProperties({"clusterConfig", "sentinelConfig"})
public static class ConfigMixIn { public static class ConfigMixIn {
@ -264,8 +229,6 @@ public class ConfigSupport {
private ObjectMapper createMapper(JsonFactory mapping, ClassLoader classLoader) { private ObjectMapper createMapper(JsonFactory mapping, ClassLoader classLoader) {
ObjectMapper mapper = new ObjectMapper(mapping); ObjectMapper mapper = new ObjectMapper(mapping);
mapper.addMixIn(MasterSlaveServersConfig.class, MasterSlaveServersConfigMixIn.class);
mapper.addMixIn(SingleServerConfig.class, SingleSeverConfigMixIn.class);
mapper.addMixIn(Config.class, ConfigMixIn.class); mapper.addMixIn(Config.class, ConfigMixIn.class);
mapper.addMixIn(ReferenceCodecProvider.class, ClassMixIn.class); mapper.addMixIn(ReferenceCodecProvider.class, ClassMixIn.class);
mapper.addMixIn(AddressResolverGroupFactory.class, ClassMixIn.class); mapper.addMixIn(AddressResolverGroupFactory.class, ClassMixIn.class);

@ -15,10 +15,9 @@
*/ */
package org.redisson.config; package org.redisson.config;
import java.net.URI; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.redisson.misc.URIBuilder;
/** /**
* *
@ -30,12 +29,12 @@ public class MasterSlaveServersConfig extends BaseMasterSlaveServersConfig<Maste
/** /**
* Redis slave servers addresses * Redis slave servers addresses
*/ */
private Set<URI> slaveAddresses = new HashSet<URI>(); private Set<String> slaveAddresses = new HashSet<String>();
/** /**
* Redis master server address * Redis master server address
*/ */
private URI masterAddress; private String masterAddress;
/** /**
* Database index used for Redis connection * Database index used for Redis connection
@ -60,23 +59,12 @@ public class MasterSlaveServersConfig extends BaseMasterSlaveServersConfig<Maste
* @return config * @return config
*/ */
public MasterSlaveServersConfig setMasterAddress(String masterAddress) { public MasterSlaveServersConfig setMasterAddress(String masterAddress) {
if (masterAddress != null) { this.masterAddress = masterAddress;
this.masterAddress = URIBuilder.create(masterAddress);
}
return this; return this;
} }
public URI getMasterAddress() { public String getMasterAddress() {
if (masterAddress != null) {
return masterAddress; return masterAddress;
} }
return null;
}
public MasterSlaveServersConfig setMasterAddress(URI masterAddress) {
if (masterAddress != null) {
this.masterAddress = masterAddress;
}
return this;
}
/** /**
* Add Redis slave server address. Use follow format -- host:port * Add Redis slave server address. Use follow format -- host:port
@ -85,19 +73,17 @@ public class MasterSlaveServersConfig extends BaseMasterSlaveServersConfig<Maste
* @return config * @return config
*/ */
public MasterSlaveServersConfig addSlaveAddress(String... addresses) { public MasterSlaveServersConfig addSlaveAddress(String... addresses) {
for (String address : addresses) { slaveAddresses.addAll(Arrays.asList(addresses));
slaveAddresses.add(URIBuilder.create(address));
}
return this; return this;
} }
public MasterSlaveServersConfig addSlaveAddress(URI slaveAddress) { public MasterSlaveServersConfig addSlaveAddress(String slaveAddress) {
slaveAddresses.add(slaveAddress); slaveAddresses.add(slaveAddress);
return this; return this;
} }
public Set<URI> getSlaveAddresses() { public Set<String> getSlaveAddresses() {
return slaveAddresses; return slaveAddresses;
} }
public void setSlaveAddresses(Set<URI> readAddresses) { public void setSlaveAddresses(Set<String> readAddresses) {
this.slaveAddresses = readAddresses; this.slaveAddresses = readAddresses;
} }

@ -15,10 +15,9 @@
*/ */
package org.redisson.config; package org.redisson.config;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import org.redisson.misc.URIBuilder;
/** /**
* Configuration for an Azure Redis Cache or AWS ElastiCache servers. * Configuration for an Azure Redis Cache or AWS ElastiCache servers.
@ -32,7 +31,7 @@ public class ReplicatedServersConfig extends BaseMasterSlaveServersConfig<Replic
/** /**
* Replication group node urls list * Replication group node urls list
*/ */
private List<URI> nodeAddresses = new ArrayList<URI>(); private List<String> nodeAddresses = new ArrayList<>();
/** /**
* Replication group scan interval in milliseconds * Replication group scan interval in milliseconds
@ -61,15 +60,13 @@ public class ReplicatedServersConfig extends BaseMasterSlaveServersConfig<Replic
* @return config * @return config
*/ */
public ReplicatedServersConfig addNodeAddress(String... addresses) { public ReplicatedServersConfig addNodeAddress(String... addresses) {
for (String address : addresses) { nodeAddresses.addAll(Arrays.asList(addresses));
nodeAddresses.add(URIBuilder.create(address));
}
return this; return this;
} }
public List<URI> getNodeAddresses() { public List<String> getNodeAddresses() {
return nodeAddresses; return nodeAddresses;
} }
void setNodeAddresses(List<URI> nodeAddresses) { void setNodeAddresses(List<String> nodeAddresses) {
this.nodeAddresses = nodeAddresses; this.nodeAddresses = nodeAddresses;
} }

@ -15,15 +15,13 @@
*/ */
package org.redisson.config; package org.redisson.config;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.redisson.misc.URIBuilder;
/** /**
* *
* @author Nikita Koksharov * @author Nikita Koksharov
@ -31,7 +29,7 @@ import org.redisson.misc.URIBuilder;
*/ */
public class SentinelServersConfig extends BaseMasterSlaveServersConfig<SentinelServersConfig> { public class SentinelServersConfig extends BaseMasterSlaveServersConfig<SentinelServersConfig> {
private List<URI> sentinelAddresses = new ArrayList<URI>(); private List<String> sentinelAddresses = new ArrayList<>();
private Map<String, String> natMap = Collections.emptyMap(); private Map<String, String> natMap = Collections.emptyMap();
@ -80,15 +78,13 @@ public class SentinelServersConfig extends BaseMasterSlaveServersConfig<Sentinel
* @return config * @return config
*/ */
public SentinelServersConfig addSentinelAddress(String... addresses) { public SentinelServersConfig addSentinelAddress(String... addresses) {
for (String address : addresses) { sentinelAddresses.addAll(Arrays.asList(addresses));
sentinelAddresses.add(URIBuilder.create(address));
}
return this; return this;
} }
public List<URI> getSentinelAddresses() { public List<String> getSentinelAddresses() {
return sentinelAddresses; return sentinelAddresses;
} }
void setSentinelAddresses(List<URI> sentinelAddresses) { void setSentinelAddresses(List<String> sentinelAddresses) {
this.sentinelAddresses = sentinelAddresses; this.sentinelAddresses = sentinelAddresses;
} }

@ -15,9 +15,6 @@
*/ */
package org.redisson.config; package org.redisson.config;
import java.net.URI;
import org.redisson.misc.URIBuilder;
/** /**
* *
* @author Nikita Koksharov * @author Nikita Koksharov
@ -29,7 +26,7 @@ public class SingleServerConfig extends BaseConfig<SingleServerConfig> {
* Redis server address * Redis server address
* *
*/ */
private URI address; private String address;
/** /**
* Minimum idle subscription connection amount * Minimum idle subscription connection amount
@ -116,21 +113,13 @@ public class SingleServerConfig extends BaseConfig<SingleServerConfig> {
*/ */
public SingleServerConfig setAddress(String address) { public SingleServerConfig setAddress(String address) {
if (address != null) { if (address != null) {
this.address = URIBuilder.create(address); this.address = address;
} }
return this; return this;
} }
public URI getAddress() { public String getAddress() {
if (address != null) {
return address; return address;
} }
return null;
}
void setAddress(URI address) {
if (address != null) {
this.address = address;
}
}
/** /**
* Interval in milliseconds to check the endpoint's DNS<p> * Interval in milliseconds to check the endpoint's DNS<p>

@ -16,7 +16,6 @@
package org.redisson.connection; package org.redisson.connection;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Collection; import java.util.Collection;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -32,6 +31,7 @@ import org.redisson.command.CommandSyncService;
import org.redisson.config.Config; import org.redisson.config.Config;
import org.redisson.config.MasterSlaveServersConfig; import org.redisson.config.MasterSlaveServersConfig;
import org.redisson.misc.InfinitySemaphoreLatch; import org.redisson.misc.InfinitySemaphoreLatch;
import org.redisson.misc.RedisURI;
import org.redisson.pubsub.PublishSubscribeService; import org.redisson.pubsub.PublishSubscribeService;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
@ -46,7 +46,7 @@ import io.netty.util.concurrent.Future;
*/ */
public interface ConnectionManager { public interface ConnectionManager {
URI applyNatMap(URI address); RedisURI applyNatMap(RedisURI address);
UUID getId(); UUID getId();
@ -56,7 +56,7 @@ public interface ConnectionManager {
ExecutorService getExecutor(); ExecutorService getExecutor();
URI getLastClusterNode(); RedisURI getLastClusterNode();
Config getCfg(); Config getCfg();
@ -92,11 +92,11 @@ public interface ConnectionManager {
RFuture<RedisConnection> connectionWriteOp(NodeSource source, RedisCommand<?> command); RFuture<RedisConnection> connectionWriteOp(NodeSource source, RedisCommand<?> command);
RedisClient createClient(NodeType type, URI address, int timeout, int commandTimeout, String sslHostname); RedisClient createClient(NodeType type, RedisURI address, int timeout, int commandTimeout, String sslHostname);
RedisClient createClient(NodeType type, InetSocketAddress address, URI uri, String sslHostname); RedisClient createClient(NodeType type, InetSocketAddress address, RedisURI uri, String sslHostname);
RedisClient createClient(NodeType type, URI address, String sslHostname); RedisClient createClient(NodeType type, RedisURI address, String sslHostname);
MasterSlaveEntry getEntry(RedisClient redisClient); MasterSlaveEntry getEntry(RedisClient redisClient);

@ -16,7 +16,6 @@
package org.redisson.connection; package org.redisson.connection;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -27,6 +26,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.redisson.api.RFuture; import org.redisson.api.RFuture;
import org.redisson.client.RedisClient; import org.redisson.client.RedisClient;
import org.redisson.connection.ClientConnectionsEntry.FreezeReason; import org.redisson.connection.ClientConnectionsEntry.FreezeReason;
import org.redisson.misc.RedisURI;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -48,19 +48,19 @@ public class DNSMonitor {
private final AddressResolver<InetSocketAddress> resolver; private final AddressResolver<InetSocketAddress> resolver;
private final ConnectionManager connectionManager; private final ConnectionManager connectionManager;
private final Map<URI, InetSocketAddress> masters = new HashMap<URI, InetSocketAddress>(); private final Map<RedisURI, InetSocketAddress> masters = new HashMap<>();
private final Map<URI, InetSocketAddress> slaves = new HashMap<URI, InetSocketAddress>(); private final Map<RedisURI, InetSocketAddress> slaves = new HashMap<>();
private ScheduledFuture<?> dnsMonitorFuture; private ScheduledFuture<?> dnsMonitorFuture;
private long dnsMonitoringInterval; private long dnsMonitoringInterval;
public DNSMonitor(ConnectionManager connectionManager, RedisClient masterHost, Collection<URI> slaveHosts, long dnsMonitoringInterval, AddressResolverGroup<InetSocketAddress> resolverGroup) { public DNSMonitor(ConnectionManager connectionManager, RedisClient masterHost, Collection<RedisURI> slaveHosts, long dnsMonitoringInterval, AddressResolverGroup<InetSocketAddress> resolverGroup) {
this.resolver = resolverGroup.getResolver(connectionManager.getGroup().next()); this.resolver = resolverGroup.getResolver(connectionManager.getGroup().next());
masterHost.resolveAddr().syncUninterruptibly(); masterHost.resolveAddr().syncUninterruptibly();
masters.put(masterHost.getConfig().getAddress(), masterHost.getAddr()); masters.put(masterHost.getConfig().getAddress(), masterHost.getAddr());
for (URI host : slaveHosts) { for (RedisURI host : slaveHosts) {
Future<InetSocketAddress> resolveFuture = resolver.resolve(InetSocketAddress.createUnresolved(host.getHost(), host.getPort())); Future<InetSocketAddress> resolveFuture = resolver.resolve(InetSocketAddress.createUnresolved(host.getHost(), host.getPort()));
resolveFuture.syncUninterruptibly(); resolveFuture.syncUninterruptibly();
slaves.put(host, resolveFuture.getNow()); slaves.put(host, resolveFuture.getNow());
@ -97,7 +97,7 @@ public class DNSMonitor {
} }
private void monitorMasters(AtomicInteger counter) { private void monitorMasters(AtomicInteger counter) {
for (Entry<URI, InetSocketAddress> entry : masters.entrySet()) { for (Entry<RedisURI, InetSocketAddress> entry : masters.entrySet()) {
Future<InetSocketAddress> resolveFuture = resolver.resolve(InetSocketAddress.createUnresolved(entry.getKey().getHost(), entry.getKey().getPort())); Future<InetSocketAddress> resolveFuture = resolver.resolve(InetSocketAddress.createUnresolved(entry.getKey().getHost(), entry.getKey().getPort()));
resolveFuture.addListener(new FutureListener<InetSocketAddress>() { resolveFuture.addListener(new FutureListener<InetSocketAddress>() {
@Override @Override
@ -134,7 +134,7 @@ public class DNSMonitor {
} }
private void monitorSlaves(AtomicInteger counter) { private void monitorSlaves(AtomicInteger counter) {
for (Entry<URI, InetSocketAddress> entry : slaves.entrySet()) { for (Entry<RedisURI, InetSocketAddress> entry : slaves.entrySet()) {
Future<InetSocketAddress> resolveFuture = resolver.resolve(InetSocketAddress.createUnresolved(entry.getKey().getHost(), entry.getKey().getPort())); Future<InetSocketAddress> resolveFuture = resolver.resolve(InetSocketAddress.createUnresolved(entry.getKey().getHost(), entry.getKey().getPort()));
resolveFuture.addListener(new FutureListener<InetSocketAddress>() { resolveFuture.addListener(new FutureListener<InetSocketAddress>() {
@Override @Override

@ -16,18 +16,19 @@
package org.redisson.connection; package org.redisson.connection;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.stream.Collectors;
import org.redisson.Version; import org.redisson.Version;
import org.redisson.api.NodeType; import org.redisson.api.NodeType;
@ -48,8 +49,8 @@ import org.redisson.config.TransportMode;
import org.redisson.misc.CountableListener; import org.redisson.misc.CountableListener;
import org.redisson.misc.InfinitySemaphoreLatch; import org.redisson.misc.InfinitySemaphoreLatch;
import org.redisson.misc.RPromise; import org.redisson.misc.RPromise;
import org.redisson.misc.RedisURI;
import org.redisson.misc.RedissonPromise; import org.redisson.misc.RedissonPromise;
import org.redisson.misc.URIBuilder;
import org.redisson.pubsub.PublishSubscribeService; import org.redisson.pubsub.PublishSubscribeService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -241,7 +242,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
} }
} }
protected RFuture<RedisConnection> connectToNode(BaseMasterSlaveServersConfig<?> cfg, URI addr, RedisClient client, String sslHostname) { protected RFuture<RedisConnection> connectToNode(BaseMasterSlaveServersConfig<?> cfg, RedisURI addr, RedisClient client, String sslHostname) {
final Object key; final Object key;
if (client != null) { if (client != null) {
key = client; key = client;
@ -342,7 +343,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
} else { } else {
entry = createMasterSlaveEntry(config); entry = createMasterSlaveEntry(config);
} }
RFuture<RedisClient> f = entry.setupMasterEntry(config.getMasterAddress()); RFuture<RedisClient> f = entry.setupMasterEntry(new RedisURI(config.getMasterAddress()));
f.syncUninterruptibly(); f.syncUninterruptibly();
for (int slot = singleSlotRange.getStartSlot(); slot < singleSlotRange.getEndSlot() + 1; slot++) { for (int slot = singleSlotRange.getStartSlot(); slot < singleSlotRange.getEndSlot() + 1; slot++) {
@ -358,15 +359,16 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
protected void startDNSMonitoring(RedisClient masterHost) { protected void startDNSMonitoring(RedisClient masterHost) {
if (config.getDnsMonitoringInterval() != -1) { if (config.getDnsMonitoringInterval() != -1) {
Set<RedisURI> slaveAddresses = config.getSlaveAddresses().stream().map(r -> new RedisURI(r)).collect(Collectors.toSet());
dnsMonitor = new DNSMonitor(this, masterHost, dnsMonitor = new DNSMonitor(this, masterHost,
config.getSlaveAddresses(), config.getDnsMonitoringInterval(), resolverGroup); slaveAddresses, config.getDnsMonitoringInterval(), resolverGroup);
dnsMonitor.start(); dnsMonitor.start();
} }
} }
protected MasterSlaveEntry createMasterSlaveEntry(MasterSlaveServersConfig config) { protected MasterSlaveEntry createMasterSlaveEntry(MasterSlaveServersConfig config) {
MasterSlaveEntry entry = new MasterSlaveEntry(this, config); MasterSlaveEntry entry = new MasterSlaveEntry(this, config);
List<RFuture<Void>> fs = entry.initSlaveBalancer(java.util.Collections.<URI>emptySet()); List<RFuture<Void>> fs = entry.initSlaveBalancer(java.util.Collections.<RedisURI>emptySet());
for (RFuture<Void> future : fs) { for (RFuture<Void> future : fs) {
future.syncUninterruptibly(); future.syncUninterruptibly();
} }
@ -412,31 +414,31 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
} }
@Override @Override
public RedisClient createClient(NodeType type, URI address, String sslHostname) { public RedisClient createClient(NodeType type, RedisURI address, String sslHostname) {
RedisClient client = createClient(type, address, config.getConnectTimeout(), config.getTimeout(), sslHostname); RedisClient client = createClient(type, address, config.getConnectTimeout(), config.getTimeout(), sslHostname);
return client; return client;
} }
@Override @Override
public RedisClient createClient(NodeType type, InetSocketAddress address, URI uri, String sslHostname) { public RedisClient createClient(NodeType type, InetSocketAddress address, RedisURI uri, String sslHostname) {
RedisClient client = createClient(type, address, uri, config.getConnectTimeout(), config.getTimeout(), sslHostname); RedisClient client = createClient(type, address, uri, config.getConnectTimeout(), config.getTimeout(), sslHostname);
return client; return client;
} }
@Override @Override
public RedisClient createClient(NodeType type, URI address, int timeout, int commandTimeout, String sslHostname) { public RedisClient createClient(NodeType type, RedisURI address, int timeout, int commandTimeout, String sslHostname) {
RedisClientConfig redisConfig = createRedisConfig(type, address, timeout, commandTimeout, sslHostname); RedisClientConfig redisConfig = createRedisConfig(type, address, timeout, commandTimeout, sslHostname);
return RedisClient.create(redisConfig); return RedisClient.create(redisConfig);
} }
private RedisClient createClient(NodeType type, InetSocketAddress address, URI uri, int timeout, int commandTimeout, String sslHostname) { private RedisClient createClient(NodeType type, InetSocketAddress address, RedisURI uri, int timeout, int commandTimeout, String sslHostname) {
RedisClientConfig redisConfig = createRedisConfig(type, null, timeout, commandTimeout, sslHostname); RedisClientConfig redisConfig = createRedisConfig(type, null, timeout, commandTimeout, sslHostname);
redisConfig.setAddress(address, uri); redisConfig.setAddress(address, uri);
return RedisClient.create(redisConfig); return RedisClient.create(redisConfig);
} }
protected RedisClientConfig createRedisConfig(NodeType type, URI address, int timeout, int commandTimeout, String sslHostname) { protected RedisClientConfig createRedisConfig(NodeType type, RedisURI address, int timeout, int commandTimeout, String sslHostname) {
RedisClientConfig redisConfig = new RedisClientConfig(); RedisClientConfig redisConfig = new RedisClientConfig();
redisConfig.setAddress(address) redisConfig.setAddress(address)
.setTimer(timer) .setTimer(timer)
@ -489,9 +491,9 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
return null; return null;
} }
private MasterSlaveEntry getEntry(URI addr) { private MasterSlaveEntry getEntry(RedisURI addr) {
for (MasterSlaveEntry entry : client2entry.values()) { for (MasterSlaveEntry entry : client2entry.values()) {
if (URIBuilder.compare(entry.getClient().getAddr(), addr)) { if (RedisURI.compare(entry.getClient().getAddr(), addr)) {
return entry; return entry;
} }
if (entry.hasSlave(addr)) { if (entry.hasSlave(addr)) {
@ -521,7 +523,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
return slot2entry.get(slot); return slot2entry.get(slot);
} }
protected final RFuture<RedisClient> changeMaster(int slot, URI address) { protected final RFuture<RedisClient> changeMaster(int slot, RedisURI address) {
final MasterSlaveEntry entry = getEntry(slot); final MasterSlaveEntry entry = getEntry(slot);
final RedisClient oldClient = entry.getClient(); final RedisClient oldClient = entry.getClient();
RFuture<RedisClient> future = entry.changeMaster(address); RFuture<RedisClient> future = entry.changeMaster(address);
@ -559,7 +561,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
} }
// fix for https://github.com/redisson/redisson/issues/1548 // fix for https://github.com/redisson/redisson/issues/1548
if (source.getRedirect() != null if (source.getRedirect() != null
&& !URIBuilder.compare(entry.getClient().getAddr(), source.getAddr()) && !RedisURI.compare(entry.getClient().getAddr(), source.getAddr())
&& entry.hasSlave(source.getAddr())) { && entry.hasSlave(source.getAddr())) {
return entry.redirectedConnectionWriteOp(command, source.getAddr()); return entry.redirectedConnectionWriteOp(command, source.getAddr());
} }
@ -714,12 +716,12 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
return executor; return executor;
} }
public URI getLastClusterNode() { public RedisURI getLastClusterNode() {
return null; return null;
} }
@Override @Override
public URI applyNatMap(URI address) { public RedisURI applyNatMap(RedisURI address) {
return address; return address;
} }
} }

@ -16,7 +16,6 @@
package org.redisson.connection; package org.redisson.connection;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -40,9 +39,9 @@ import org.redisson.connection.pool.MasterConnectionPool;
import org.redisson.connection.pool.MasterPubSubConnectionPool; import org.redisson.connection.pool.MasterPubSubConnectionPool;
import org.redisson.misc.CountableListener; import org.redisson.misc.CountableListener;
import org.redisson.misc.RPromise; import org.redisson.misc.RPromise;
import org.redisson.misc.RedisURI;
import org.redisson.misc.RedissonPromise; import org.redisson.misc.RedissonPromise;
import org.redisson.misc.TransferListener; import org.redisson.misc.TransferListener;
import org.redisson.misc.URIBuilder;
import org.redisson.pubsub.PubSubConnectionEntry; import org.redisson.pubsub.PubSubConnectionEntry;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -92,28 +91,29 @@ public class MasterSlaveEntry {
return config; return config;
} }
public List<RFuture<Void>> initSlaveBalancer(Collection<URI> disconnectedNodes) { public List<RFuture<Void>> initSlaveBalancer(Collection<RedisURI> disconnectedNodes) {
boolean freezeMasterAsSlave = !config.getSlaveAddresses().isEmpty() boolean freezeMasterAsSlave = !config.getSlaveAddresses().isEmpty()
&& !config.checkSkipSlavesInit() && !config.checkSkipSlavesInit()
&& disconnectedNodes.size() < config.getSlaveAddresses().size(); && disconnectedNodes.size() < config.getSlaveAddresses().size();
List<RFuture<Void>> result = new LinkedList<RFuture<Void>>(); List<RFuture<Void>> result = new LinkedList<RFuture<Void>>();
RFuture<Void> f = addSlave(config.getMasterAddress(), freezeMasterAsSlave, NodeType.MASTER); RFuture<Void> f = addSlave(new RedisURI(config.getMasterAddress()), freezeMasterAsSlave, NodeType.MASTER);
result.add(f); result.add(f);
for (URI address : config.getSlaveAddresses()) { for (String address : config.getSlaveAddresses()) {
f = addSlave(address, disconnectedNodes.contains(address), NodeType.SLAVE); RedisURI uri = new RedisURI(address);
f = addSlave(uri, disconnectedNodes.contains(uri), NodeType.SLAVE);
result.add(f); result.add(f);
} }
return result; return result;
} }
public RFuture<RedisClient> setupMasterEntry(InetSocketAddress address, URI uri) { public RFuture<RedisClient> setupMasterEntry(InetSocketAddress address, RedisURI uri) {
RedisClient client = connectionManager.createClient(NodeType.MASTER, address, uri, sslHostname); RedisClient client = connectionManager.createClient(NodeType.MASTER, address, uri, sslHostname);
return setupMasterEntry(client); return setupMasterEntry(client);
} }
public RFuture<RedisClient> setupMasterEntry(URI address) { public RFuture<RedisClient> setupMasterEntry(RedisURI address) {
RedisClient client = connectionManager.createClient(NodeType.MASTER, address, sslHostname); RedisClient client = connectionManager.createClient(NodeType.MASTER, address, sslHostname);
return setupMasterEntry(client); return setupMasterEntry(client);
} }
@ -173,7 +173,7 @@ public class MasterSlaveEntry {
return slaveDown(entry); return slaveDown(entry);
} }
public boolean slaveDown(URI address, FreezeReason freezeReason) { public boolean slaveDown(RedisURI address, FreezeReason freezeReason) {
ClientConnectionsEntry entry = slaveBalancer.freeze(address, freezeReason); ClientConnectionsEntry entry = slaveBalancer.freeze(address, freezeReason);
if (entry == null) { if (entry == null) {
return false; return false;
@ -276,7 +276,7 @@ public class MasterSlaveEntry {
return slaveBalancer.contains(addr); return slaveBalancer.contains(addr);
} }
public boolean hasSlave(URI addr) { public boolean hasSlave(RedisURI addr) {
return slaveBalancer.contains(addr); return slaveBalancer.contains(addr);
} }
@ -284,11 +284,11 @@ public class MasterSlaveEntry {
return slaveBalancer.getAvailableClients(); return slaveBalancer.getAvailableClients();
} }
public RFuture<Void> addSlave(URI address) { public RFuture<Void> addSlave(RedisURI address) {
return addSlave(address, false, NodeType.SLAVE); return addSlave(address, false, NodeType.SLAVE);
} }
public RFuture<Void> addSlave(InetSocketAddress address, URI uri) { public RFuture<Void> addSlave(InetSocketAddress address, RedisURI uri) {
return addSlave(address, uri, false, NodeType.SLAVE); return addSlave(address, uri, false, NodeType.SLAVE);
} }
@ -323,12 +323,12 @@ public class MasterSlaveEntry {
return result; return result;
} }
private RFuture<Void> addSlave(InetSocketAddress address, URI uri, boolean freezed, NodeType nodeType) { private RFuture<Void> addSlave(InetSocketAddress address, RedisURI uri, boolean freezed, NodeType nodeType) {
RedisClient client = connectionManager.createClient(NodeType.SLAVE, address, uri, sslHostname); RedisClient client = connectionManager.createClient(NodeType.SLAVE, address, uri, sslHostname);
return addSlave(client, freezed, nodeType); return addSlave(client, freezed, nodeType);
} }
private RFuture<Void> addSlave(URI address, boolean freezed, NodeType nodeType) { private RFuture<Void> addSlave(RedisURI address, boolean freezed, NodeType nodeType) {
RedisClient client = connectionManager.createClient(nodeType, address, sslHostname); RedisClient client = connectionManager.createClient(nodeType, address, sslHostname);
return addSlave(client, freezed, nodeType); return addSlave(client, freezed, nodeType);
} }
@ -361,11 +361,11 @@ public class MasterSlaveEntry {
return true; return true;
} }
public boolean isSlaveUnfreezed(URI address) { public boolean isSlaveUnfreezed(RedisURI address) {
return slaveBalancer.isUnfreezed(address); return slaveBalancer.isUnfreezed(address);
} }
public boolean slaveUp(URI address, FreezeReason freezeReason) { public boolean slaveUp(RedisURI address, FreezeReason freezeReason) {
if (!slaveBalancer.unfreeze(address, freezeReason)) { if (!slaveBalancer.unfreeze(address, freezeReason)) {
return false; return false;
} }
@ -373,7 +373,7 @@ public class MasterSlaveEntry {
InetSocketAddress addr = masterEntry.getClient().getAddr(); InetSocketAddress addr = masterEntry.getClient().getAddr();
// exclude master from slaves // exclude master from slaves
if (!config.checkSkipSlavesInit() if (!config.checkSkipSlavesInit()
&& !URIBuilder.compare(addr, address)) { && !RedisURI.compare(addr, address)) {
if (slaveDown(addr, FreezeReason.SYSTEM)) { if (slaveDown(addr, FreezeReason.SYSTEM)) {
log.info("master {} excluded from slaves", addr); log.info("master {} excluded from slaves", addr);
} }
@ -406,21 +406,21 @@ public class MasterSlaveEntry {
* @param address of Redis * @param address of Redis
* @return client * @return client
*/ */
public RFuture<RedisClient> changeMaster(URI address) { public RFuture<RedisClient> changeMaster(RedisURI address) {
ClientConnectionsEntry oldMaster = masterEntry; ClientConnectionsEntry oldMaster = masterEntry;
RFuture<RedisClient> future = setupMasterEntry(address); RFuture<RedisClient> future = setupMasterEntry(address);
changeMaster(address, oldMaster, future); changeMaster(address, oldMaster, future);
return future; return future;
} }
public void changeMaster(InetSocketAddress address, URI uri) { public void changeMaster(InetSocketAddress address, RedisURI uri) {
ClientConnectionsEntry oldMaster = masterEntry; ClientConnectionsEntry oldMaster = masterEntry;
RFuture<RedisClient> future = setupMasterEntry(address, uri); RFuture<RedisClient> future = setupMasterEntry(address, uri);
changeMaster(uri, oldMaster, future); changeMaster(uri, oldMaster, future);
} }
private void changeMaster(URI address, ClientConnectionsEntry oldMaster, private void changeMaster(RedisURI address, ClientConnectionsEntry oldMaster,
RFuture<RedisClient> future) { RFuture<RedisClient> future) {
future.onComplete((newMasterClient, e) -> { future.onComplete((newMasterClient, e) -> {
if (e != null) { if (e != null) {
@ -471,7 +471,7 @@ public class MasterSlaveEntry {
return writeConnectionPool.get(command); return writeConnectionPool.get(command);
} }
public RFuture<RedisConnection> redirectedConnectionWriteOp(RedisCommand<?> command, URI addr) { public RFuture<RedisConnection> redirectedConnectionWriteOp(RedisCommand<?> command, RedisURI addr) {
return slaveBalancer.getConnection(command, addr); return slaveBalancer.getConnection(command, addr);
} }
@ -482,7 +482,7 @@ public class MasterSlaveEntry {
return slaveBalancer.nextConnection(command); return slaveBalancer.nextConnection(command);
} }
public RFuture<RedisConnection> connectionReadOp(RedisCommand<?> command, URI addr) { public RFuture<RedisConnection> connectionReadOp(RedisCommand<?> command, RedisURI addr) {
return slaveBalancer.getConnection(command, addr); return slaveBalancer.getConnection(command, addr);
} }

@ -15,9 +15,8 @@
*/ */
package org.redisson.connection; package org.redisson.connection;
import java.net.URI;
import org.redisson.client.RedisClient; import org.redisson.client.RedisClient;
import org.redisson.misc.RedisURI;
/** /**
* *
@ -29,7 +28,7 @@ public class NodeSource {
public enum Redirect {MOVED, ASK} public enum Redirect {MOVED, ASK}
private Integer slot; private Integer slot;
private URI addr; private RedisURI addr;
private RedisClient redisClient; private RedisClient redisClient;
private Redirect redirect; private Redirect redirect;
private MasterSlaveEntry entry; private MasterSlaveEntry entry;
@ -52,7 +51,7 @@ public class NodeSource {
this.redisClient = redisClient; this.redisClient = redisClient;
} }
public NodeSource(Integer slot, URI addr, Redirect redirect) { public NodeSource(Integer slot, RedisURI addr, Redirect redirect) {
this.slot = slot; this.slot = slot;
this.addr = addr; this.addr = addr;
this.redirect = redirect; this.redirect = redirect;
@ -74,7 +73,7 @@ public class NodeSource {
return redisClient; return redisClient;
} }
public URI getAddr() { public RedisURI getAddr() {
return addr; return addr;
} }

@ -15,7 +15,6 @@
*/ */
package org.redisson.connection; package org.redisson.connection;
import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -34,6 +33,7 @@ import org.redisson.config.MasterSlaveServersConfig;
import org.redisson.config.ReadMode; import org.redisson.config.ReadMode;
import org.redisson.config.ReplicatedServersConfig; import org.redisson.config.ReplicatedServersConfig;
import org.redisson.connection.ClientConnectionsEntry.FreezeReason; import org.redisson.connection.ClientConnectionsEntry.FreezeReason;
import org.redisson.misc.RedisURI;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -53,7 +53,7 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager {
private final Logger log = LoggerFactory.getLogger(getClass()); private final Logger log = LoggerFactory.getLogger(getClass());
private AtomicReference<URI> currentMaster = new AtomicReference<URI>(); private AtomicReference<RedisURI> currentMaster = new AtomicReference<>();
private ScheduledFuture<?> monitorFuture; private ScheduledFuture<?> monitorFuture;
@ -68,7 +68,8 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager {
this.config = create(cfg); this.config = create(cfg);
initTimer(this.config); initTimer(this.config);
for (URI addr : cfg.getNodeAddresses()) { for (String address : cfg.getNodeAddresses()) {
RedisURI addr = new RedisURI(address);
RFuture<RedisConnection> connectionFuture = connectToNode(cfg, addr, null, addr.getHost()); RFuture<RedisConnection> connectionFuture = connectToNode(cfg, addr, null, addr.getHost());
connectionFuture.awaitUninterruptibly(); connectionFuture.awaitUninterruptibly();
RedisConnection connection = connectionFuture.getNow(); RedisConnection connection = connectionFuture.getNow();
@ -84,10 +85,10 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager {
} }
currentMaster.set(addr); currentMaster.set(addr);
log.info("{} is the master", addr); log.info("{} is the master", addr);
this.config.setMasterAddress(addr); this.config.setMasterAddress(addr.toString());
} else { } else {
log.info("{} is a slave", addr); log.info("{} is a slave", addr);
this.config.addSlaveAddress(addr); this.config.addSlaveAddress(addr.toString());
} }
} }
@ -123,11 +124,12 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager {
return; return;
} }
URI master = currentMaster.get(); RedisURI master = currentMaster.get();
log.debug("Current master: {}", master); log.debug("Current master: {}", master);
AtomicInteger count = new AtomicInteger(cfg.getNodeAddresses().size()); AtomicInteger count = new AtomicInteger(cfg.getNodeAddresses().size());
for (URI addr : cfg.getNodeAddresses()) { for (String address : cfg.getNodeAddresses()) {
RedisURI addr = new RedisURI(address);
RFuture<RedisConnection> connectionFuture = connectToNode(cfg, addr, null, addr.getHost()); RFuture<RedisConnection> connectionFuture = connectToNode(cfg, addr, null, addr.getHost());
connectionFuture.onComplete((connection, exc) -> { connectionFuture.onComplete((connection, exc) -> {
if (exc != null) { if (exc != null) {
@ -180,7 +182,7 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager {
}, cfg.getScanInterval(), TimeUnit.MILLISECONDS); }, cfg.getScanInterval(), TimeUnit.MILLISECONDS);
} }
private void slaveUp(URI uri) { private void slaveUp(RedisURI uri) {
MasterSlaveEntry entry = getEntry(singleSlotRange.getStartSlot()); MasterSlaveEntry entry = getEntry(singleSlotRange.getStartSlot());
if (entry.slaveUp(uri, FreezeReason.MANAGER)) { if (entry.slaveUp(uri, FreezeReason.MANAGER)) {
log.info("slave: {} has up", uri); log.info("slave: {} has up", uri);

@ -16,7 +16,6 @@
package org.redisson.connection; package org.redisson.connection;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -52,8 +51,8 @@ import org.redisson.config.SentinelServersConfig;
import org.redisson.connection.ClientConnectionsEntry.FreezeReason; import org.redisson.connection.ClientConnectionsEntry.FreezeReason;
import org.redisson.misc.CountableListener; import org.redisson.misc.CountableListener;
import org.redisson.misc.RPromise; import org.redisson.misc.RPromise;
import org.redisson.misc.RedisURI;
import org.redisson.misc.RedissonPromise; import org.redisson.misc.RedissonPromise;
import org.redisson.misc.URIBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -72,11 +71,11 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
private final Logger log = LoggerFactory.getLogger(getClass()); private final Logger log = LoggerFactory.getLogger(getClass());
private final Set<URI> sentinelHosts = new HashSet<>(); private final Set<RedisURI> sentinelHosts = new HashSet<>();
private final ConcurrentMap<URI, RedisClient> sentinels = new ConcurrentHashMap<>(); private final ConcurrentMap<RedisURI, RedisClient> sentinels = new ConcurrentHashMap<>();
private final AtomicReference<String> currentMaster = new AtomicReference<>(); private final AtomicReference<String> currentMaster = new AtomicReference<>();
private final Set<URI> disconnectedSlaves = new HashSet<>(); private final Set<RedisURI> disconnectedSlaves = new HashSet<>();
private ScheduledFuture<?> monitorFuture; private ScheduledFuture<?> monitorFuture;
private AddressResolver<InetSocketAddress> sentinelResolver; private AddressResolver<InetSocketAddress> sentinelResolver;
@ -101,7 +100,8 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
this.sentinelResolver = resolverGroup.getResolver(getGroup().next()); this.sentinelResolver = resolverGroup.getResolver(getGroup().next());
for (URI addr : cfg.getSentinelAddresses()) { for (String address : cfg.getSentinelAddresses()) {
RedisURI addr = new RedisURI(address);
RedisClient client = createClient(NodeType.SENTINEL, addr, this.config.getConnectTimeout(), this.config.getRetryInterval() * this.config.getRetryAttempts(), null); RedisClient client = createClient(NodeType.SENTINEL, addr, this.config.getConnectTimeout(), this.config.getRetryInterval() * this.config.getRetryAttempts(), null);
try { try {
RedisConnection c = client.connect(); RedisConnection c = client.connect();
@ -117,7 +117,8 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
} }
} }
for (URI addr : cfg.getSentinelAddresses()) { for (String address : cfg.getSentinelAddresses()) {
RedisURI addr = new RedisURI(address);
if (NetUtil.createByteArrayFromIpAddressString(addr.getHost()) == null && !addr.getHost().equals("localhost")) { if (NetUtil.createByteArrayFromIpAddressString(addr.getHost()) == null && !addr.getHost().equals("localhost")) {
sentinelHosts.add(convert(addr.getHost(), "" + addr.getPort())); sentinelHosts.add(convert(addr.getHost(), "" + addr.getPort()));
} }
@ -156,7 +157,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
log.info("slave: {} added", host); log.info("slave: {} added", host);
if (flags.contains("s_down") || flags.contains("disconnected")) { if (flags.contains("s_down") || flags.contains("disconnected")) {
URI uri = URIBuilder.create(host); RedisURI uri = new RedisURI(host);
disconnectedSlaves.add(uri); disconnectedSlaves.add(uri);
log.warn("slave: {} is down", host); log.warn("slave: {} is down", host);
} }
@ -172,12 +173,12 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
String ip = map.get("ip"); String ip = map.get("ip");
String port = map.get("port"); String port = map.get("port");
URI sentinelAddr = convert(ip, port); RedisURI sentinelAddr = convert(ip, port);
RFuture<Void> future = registerSentinel(sentinelAddr, this.config); RFuture<Void> future = registerSentinel(sentinelAddr, this.config);
connectionFutures.add(future); connectionFutures.add(future);
} }
URI currentAddr = convert(client.getAddr().getAddress().getHostAddress(), "" + client.getAddr().getPort()); RedisURI currentAddr = convert(client.getAddr().getAddress().getHostAddress(), "" + client.getAddr().getPort());
RFuture<Void> f = registerSentinel(currentAddr, this.config); RFuture<Void> f = registerSentinel(currentAddr, this.config);
connectionFutures.add(f); connectionFutures.add(f);
@ -221,7 +222,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
} }
@Override @Override
protected RedisClientConfig createRedisConfig(NodeType type, URI address, int timeout, int commandTimeout, protected RedisClientConfig createRedisConfig(NodeType type, RedisURI address, int timeout, int commandTimeout,
String sslHostname) { String sslHostname) {
RedisClientConfig result = super.createRedisConfig(type, address, timeout, commandTimeout, sslHostname); RedisClientConfig result = super.createRedisConfig(type, address, timeout, commandTimeout, sslHostname);
if (type == NodeType.SENTINEL && !usePassword) { if (type == NodeType.SENTINEL && !usePassword) {
@ -244,7 +245,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
} }
}; };
for (URI host : sentinelHosts) { for (RedisURI host : sentinelHosts) {
Future<List<InetSocketAddress>> allNodes = sentinelResolver.resolveAll(InetSocketAddress.createUnresolved(host.getHost(), host.getPort())); Future<List<InetSocketAddress>> allNodes = sentinelResolver.resolveAll(InetSocketAddress.createUnresolved(host.getHost(), host.getPort()));
allNodes.addListener(new FutureListener<List<InetSocketAddress>>() { allNodes.addListener(new FutureListener<List<InetSocketAddress>>() {
@Override @Override
@ -254,11 +255,11 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
return; return;
} }
Set<URI> newUris = future.getNow().stream() Set<RedisURI> newUris = future.getNow().stream()
.map(addr -> convert(addr.getAddress().getHostAddress(), "" + addr.getPort())) .map(addr -> convert(addr.getAddress().getHostAddress(), "" + addr.getPort()))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
for (URI uri : newUris) { for (RedisURI uri : newUris) {
if (!sentinels.containsKey(uri)) { if (!sentinels.containsKey(uri)) {
registerSentinel(uri, getConfig()); registerSentinel(uri, getConfig());
} }
@ -348,7 +349,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
String newMaster = createAddress(master.get(0), master.get(1)); String newMaster = createAddress(master.get(0), master.get(1));
if (!newMaster.equals(current) if (!newMaster.equals(current)
&& currentMaster.compareAndSet(current, newMaster)) { && currentMaster.compareAndSet(current, newMaster)) {
RFuture<RedisClient> changeFuture = changeMaster(singleSlotRange.getStartSlot(), URIBuilder.create(newMaster)); RFuture<RedisClient> changeFuture = changeMaster(singleSlotRange.getStartSlot(), new RedisURI(newMaster));
changeFuture.onComplete((res, ex) -> { changeFuture.onComplete((res, ex) -> {
if (ex != null) { if (ex != null) {
currentMaster.compareAndSet(newMaster, current); currentMaster.compareAndSet(newMaster, current);
@ -432,7 +433,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
return; return;
} }
Set<URI> newUris = list.stream().filter(m -> { Set<RedisURI> newUris = list.stream().filter(m -> {
String flags = m.get("flags"); String flags = m.get("flags");
if (!m.isEmpty() && !flags.contains("disconnected") && !flags.contains("s_down")) { if (!m.isEmpty() && !flags.contains("disconnected") && !flags.contains("s_down")) {
return true; return true;
@ -445,7 +446,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
}).collect(Collectors.toSet()); }).collect(Collectors.toSet());
InetSocketAddress addr = connection.getRedisClient().getAddr(); InetSocketAddress addr = connection.getRedisClient().getAddr();
URI currentAddr = convert(addr.getAddress().getHostAddress(), "" + addr.getPort()); RedisURI currentAddr = convert(addr.getAddress().getHostAddress(), "" + addr.getPort());
newUris.add(currentAddr); newUris.add(currentAddr);
updateSentinels(newUris); updateSentinels(newUris);
@ -453,17 +454,17 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
sentinelsFuture.onComplete(commonListener); sentinelsFuture.onComplete(commonListener);
} }
private void updateSentinels(Set<URI> newUris) { private void updateSentinels(Set<RedisURI> newUris) {
Set<URI> currentUris = new HashSet<>(SentinelConnectionManager.this.sentinels.keySet()); Set<RedisURI> currentUris = new HashSet<>(SentinelConnectionManager.this.sentinels.keySet());
Set<URI> addedUris = new HashSet<>(newUris); Set<RedisURI> addedUris = new HashSet<>(newUris);
addedUris.removeAll(currentUris); addedUris.removeAll(currentUris);
for (URI uri : addedUris) { for (RedisURI uri : addedUris) {
registerSentinel(uri, getConfig()); registerSentinel(uri, getConfig());
} }
currentUris.removeAll(newUris); currentUris.removeAll(newUris);
for (URI uri : currentUris) { for (RedisURI uri : currentUris) {
RedisClient sentinel = SentinelConnectionManager.this.sentinels.remove(uri); RedisClient sentinel = SentinelConnectionManager.this.sentinels.remove(uri);
if (sentinel != null) { if (sentinel != null) {
sentinel.shutdownAsync(); sentinel.shutdownAsync();
@ -495,7 +496,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
return entry; return entry;
} }
private RFuture<Void> registerSentinel(URI addr, MasterSlaveServersConfig c) { private RFuture<Void> registerSentinel(RedisURI addr, MasterSlaveServersConfig c) {
RedisClient sentinel = sentinels.get(addr); RedisClient sentinel = sentinels.get(addr);
if (sentinel != null) { if (sentinel != null) {
return RedissonPromise.newSucceededFuture(null); return RedissonPromise.newSucceededFuture(null);
@ -521,9 +522,9 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
RPromise<Void> result = new RedissonPromise<Void>(); RPromise<Void> result = new RedissonPromise<Void>();
// to avoid addition twice // to avoid addition twice
MasterSlaveEntry entry = getEntry(singleSlotRange.getStartSlot()); MasterSlaveEntry entry = getEntry(singleSlotRange.getStartSlot());
URI uri = convert(ip, port); RedisURI uri = convert(ip, port);
if (!entry.hasSlave(uri) && !config.checkSkipSlavesInit()) { if (!entry.hasSlave(uri) && !config.checkSkipSlavesInit()) {
RFuture<Void> future = entry.addSlave(URIBuilder.create(addr)); RFuture<Void> future = entry.addSlave(new RedisURI(addr));
future.onComplete((res, e) -> { future.onComplete((res, e) -> {
if (e != null) { if (e != null) {
result.tryFailure(e); result.tryFailure(e);
@ -546,9 +547,9 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
return result; return result;
} }
private URI convert(String ip, String port) { private RedisURI convert(String ip, String port) {
String addr = createAddress(ip, port); String addr = createAddress(ip, port);
URI uri = URIBuilder.create(addr); RedisURI uri = new RedisURI(addr);
return uri; return uri;
} }
@ -557,7 +558,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
log.warn("slave: {}:{} has down", ip, port); log.warn("slave: {}:{} has down", ip, port);
} else { } else {
MasterSlaveEntry entry = getEntry(singleSlotRange.getStartSlot()); MasterSlaveEntry entry = getEntry(singleSlotRange.getStartSlot());
URI uri = convert(ip, port); RedisURI uri = convert(ip, port);
if (entry.slaveDown(uri, FreezeReason.MANAGER)) { if (entry.slaveDown(uri, FreezeReason.MANAGER)) {
log.warn("slave: {}:{} has down", ip, port); log.warn("slave: {}:{} has down", ip, port);
} }
@ -581,7 +582,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
return; return;
} }
URI uri = convert(ip, port); RedisURI uri = convert(ip, port);
if (getEntry(singleSlotRange.getStartSlot()).slaveUp(uri, FreezeReason.MANAGER)) { if (getEntry(singleSlotRange.getStartSlot()).slaveUp(uri, FreezeReason.MANAGER)) {
String slaveAddr = ip + ":" + port; String slaveAddr = ip + ":" + port;
log.info("slave: {} has up", slaveAddr); log.info("slave: {} has up", slaveAddr);

@ -15,12 +15,11 @@
*/ */
package org.redisson.connection; package org.redisson.connection;
import java.net.URI;
import org.redisson.api.RFuture; import org.redisson.api.RFuture;
import org.redisson.client.RedisConnection; import org.redisson.client.RedisConnection;
import org.redisson.client.protocol.RedisCommand; import org.redisson.client.protocol.RedisCommand;
import org.redisson.config.MasterSlaveServersConfig; import org.redisson.config.MasterSlaveServersConfig;
import org.redisson.misc.RedisURI;
/** /**
* *
@ -34,7 +33,7 @@ public class SingleEntry extends MasterSlaveEntry {
} }
@Override @Override
public RFuture<RedisConnection> connectionReadOp(RedisCommand<?> command, URI addr) { public RFuture<RedisConnection> connectionReadOp(RedisCommand<?> command, RedisURI addr) {
return super.connectionWriteOp(command); return super.connectionWriteOp(command);
} }

@ -16,7 +16,6 @@
package org.redisson.connection.balancer; package org.redisson.connection.balancer;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -39,8 +38,8 @@ import org.redisson.connection.pool.PubSubConnectionPool;
import org.redisson.connection.pool.SlaveConnectionPool; import org.redisson.connection.pool.SlaveConnectionPool;
import org.redisson.misc.CountableListener; import org.redisson.misc.CountableListener;
import org.redisson.misc.RPromise; import org.redisson.misc.RPromise;
import org.redisson.misc.RedisURI;
import org.redisson.misc.RedissonPromise; import org.redisson.misc.RedissonPromise;
import org.redisson.misc.URIBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -107,7 +106,7 @@ public class LoadBalancerManager {
return count; return count;
} }
public boolean unfreeze(URI address, FreezeReason freezeReason) { public boolean unfreeze(RedisURI address, FreezeReason freezeReason) {
ClientConnectionsEntry entry = getEntry(address); ClientConnectionsEntry entry = getEntry(address);
if (entry == null) { if (entry == null) {
throw new IllegalStateException("Can't find " + address + " in slaves!"); throw new IllegalStateException("Can't find " + address + " in slaves!");
@ -145,7 +144,7 @@ public class LoadBalancerManager {
return false; return false;
} }
public ClientConnectionsEntry freeze(URI address, FreezeReason freezeReason) { public ClientConnectionsEntry freeze(RedisURI address, FreezeReason freezeReason) {
ClientConnectionsEntry connectionEntry = getEntry(address); ClientConnectionsEntry connectionEntry = getEntry(address);
return freeze(connectionEntry, freezeReason); return freeze(connectionEntry, freezeReason);
} }
@ -190,12 +189,12 @@ public class LoadBalancerManager {
return getEntry(addr) != null; return getEntry(addr) != null;
} }
public boolean isUnfreezed(URI addr) { public boolean isUnfreezed(RedisURI addr) {
ClientConnectionsEntry entry = getEntry(addr); ClientConnectionsEntry entry = getEntry(addr);
return !entry.isFreezed(); return !entry.isFreezed();
} }
public boolean contains(URI addr) { public boolean contains(RedisURI addr) {
return getEntry(addr) != null; return getEntry(addr) != null;
} }
@ -203,10 +202,10 @@ public class LoadBalancerManager {
return getEntry(redisClient) != null; return getEntry(redisClient) != null;
} }
private ClientConnectionsEntry getEntry(URI addr) { private ClientConnectionsEntry getEntry(RedisURI addr) {
for (ClientConnectionsEntry entry : client2Entry.values()) { for (ClientConnectionsEntry entry : client2Entry.values()) {
InetSocketAddress entryAddr = entry.getClient().getAddr(); InetSocketAddress entryAddr = entry.getClient().getAddr();
if (URIBuilder.compare(entryAddr, addr)) { if (RedisURI.compare(entryAddr, addr)) {
return entry; return entry;
} }
} }
@ -227,7 +226,7 @@ public class LoadBalancerManager {
return client2Entry.get(redisClient); return client2Entry.get(redisClient);
} }
public RFuture<RedisConnection> getConnection(RedisCommand<?> command, URI addr) { public RFuture<RedisConnection> getConnection(RedisCommand<?> command, RedisURI addr) {
ClientConnectionsEntry entry = getEntry(addr); ClientConnectionsEntry entry = getEntry(addr);
if (entry != null) { if (entry != null) {
return slaveConnectionPool.get(command, entry); return slaveConnectionPool.get(command, entry);

@ -16,7 +16,6 @@
package org.redisson.connection.balancer; package org.redisson.connection.balancer;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -29,7 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.redisson.connection.ClientConnectionsEntry; import org.redisson.connection.ClientConnectionsEntry;
import org.redisson.misc.URIBuilder; import org.redisson.misc.RedisURI;
/** /**
* Weighted Round Robin balancer. * Weighted Round Robin balancer.
@ -77,7 +76,7 @@ public class WeightedRoundRobinBalancer implements LoadBalancer {
*/ */
public WeightedRoundRobinBalancer(Map<String, Integer> weights, int defaultWeight) { public WeightedRoundRobinBalancer(Map<String, Integer> weights, int defaultWeight) {
for (Entry<String, Integer> entry : weights.entrySet()) { for (Entry<String, Integer> entry : weights.entrySet()) {
URI uri = URIBuilder.create(entry.getKey()); RedisURI uri = new RedisURI(entry.getKey());
InetSocketAddress addr = new InetSocketAddress(uri.getHost(), uri.getPort()); InetSocketAddress addr = new InetSocketAddress(uri.getHost(), uri.getPort());
if (entry.getValue() <= 0) { if (entry.getValue() <= 0) {
throw new IllegalArgumentException("Weight can't be less than or equal zero"); throw new IllegalArgumentException("Weight can't be less than or equal zero");

@ -0,0 +1,127 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.misc;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
/**
*
* @author Nikita Koksharov
*
*/
public class RedisURI {
private final boolean ssl;
private final String host;
private final int port;
public RedisURI(String uri) {
if (!uri.startsWith("redis://")
&& !uri.startsWith("rediss://")) {
throw new IllegalArgumentException("Redis url should start with redis:// or rediss:// (for SSL connection)");
}
String urlHost = uri.replaceFirst("redis://", "http://").replaceFirst("rediss://", "http://");
String ipV6Host = uri.substring(uri.indexOf("://")+3, uri.lastIndexOf(":"));
if (ipV6Host.contains(":")) {
urlHost = urlHost.replace(ipV6Host, "[" + ipV6Host + "]");
}
try {
URL url = new URL(urlHost);
host = url.getHost();
port = url.getPort();
ssl = uri.startsWith("rediss://");
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
}
public String getScheme() {
if (ssl) {
return "rediss";
}
return "redis";
}
public boolean isSsl() {
return ssl;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
private static String trimIpv6Brackets(String host) {
if (host.startsWith("[") && host.endsWith("]")) {
return host.substring(1, host.length() - 1);
}
return host;
}
public static boolean compare(InetSocketAddress entryAddr, RedisURI addr) {
if (((entryAddr.getHostName() != null && entryAddr.getHostName().equals(trimIpv6Brackets(addr.getHost())))
|| entryAddr.getAddress().getHostAddress().equals(trimIpv6Brackets(addr.getHost())))
&& entryAddr.getPort() == addr.getPort()) {
return true;
}
return false;
}
@Override
@SuppressWarnings("AvoidInlineConditionals")
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((host == null) ? 0 : host.hashCode());
result = prime * result + port;
result = prime * result + (ssl ? 1231 : 1237);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RedisURI other = (RedisURI) obj;
if (host == null) {
if (other.host != null)
return false;
} else if (!host.equals(other.host))
return false;
if (port != other.port)
return false;
if (ssl != other.ssl)
return false;
return true;
}
@Override
public String toString() {
return getScheme() + "://" + host + ":" + port;
}
}

@ -1,90 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.misc;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.InetSocketAddress;
import java.net.URI;
/**
*
* @author Rui Gu (https://github.com/jackygurui)
*/
public class URIBuilder {
public static URI create(String uri) {
if (!uri.startsWith("redis://")
&& !uri.startsWith("rediss://")) {
throw new IllegalArgumentException("Redis url should start with redis:// or rediss:// (for SSL connection)");
}
URI u = URI.create(uri);
// Let's assuming most of the time it is OK.
if (u.getHost() != null) {
return u;
}
String s = uri.substring(0, uri.lastIndexOf(":")).replaceFirst("redis://", "").replaceFirst("rediss://", "");
// Assuming this is an IPv6 format, other situations will be handled by
// Netty at a later stage.
return URI.create(uri.replace(s, "[" + s + "]"));
}
public static void patchUriObject() {
try {
patchUriField(35184372088832L, "L_DASH");
patchUriField(2147483648L, "H_DASH");
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
private static void patchUriField(Long maskValue, String fieldName)
throws IOException {
try {
Field field = URI.class.getDeclaredField(fieldName);
Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.setAccessible(true);
field.setLong(null, maskValue);
} catch (NoSuchFieldException e) {
// skip for Android platform
} catch (Exception e) {
throw new IOException(e);
}
}
private static String trimIpv6Brackets(String host) {
if (host.startsWith("[") && host.endsWith("]")) {
return host.substring(1, host.length() - 1);
}
return host;
}
public static boolean compare(InetSocketAddress entryAddr, URI addr) {
if (((entryAddr.getHostName() != null && entryAddr.getHostName().equals(trimIpv6Brackets(addr.getHost())))
|| entryAddr.getAddress().getHostAddress().equals(trimIpv6Brackets(addr.getHost())))
&& entryAddr.getPort() == addr.getPort()) {
return true;
}
return false;
}
}
Loading…
Cancel
Save