Skip to content

Commit 9312acc

Browse files
JuneYubggivo
andauthored
docs: Improve Javadoc for HostAndPortMapper (#4112) (#4227)
* docs: Improve Javadoc for HostAndPortMapper (#4112) * docs: Improve Javadoc for HostAndPortMapper (#4112) * docs: update HostAndPortMapper usage to use DefaultJedisClientConfig (#4112) * docs: update HostAndMapper advanced-usage.md * docs: add example use case * update wordlist --------- Co-authored-by: ggivo <[email protected]>
1 parent 854b24a commit 9312acc

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

.github/wordlist.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ ClusterPipeline
1717
ClusterPubSub
1818
ConnectionPool
1919
CoreCommands
20+
config
2021
Dockerfile
2122
EVAL
2223
EVALSHA
@@ -34,6 +35,7 @@ GeoUnit
3435
GraphCommands
3536
Grokzen's
3637
HostAndPort
38+
HostAndPortMapper
3739
HostnameVerifier
3840
INCR
3941
IOError
@@ -83,6 +85,7 @@ RedisInstrumentor
8385
RedisJSON
8486
RedisTimeSeries
8587
Redislabs
88+
reusability
8689
SHA
8790
SSLParameters
8891
SSLSocketFactory
@@ -199,6 +202,7 @@ keyspace
199202
keysvalues
200203
kllayn
201204
kwarg
205+
Kubernetes
202206
lastName
203207
lastsave
204208
learningpath

docs/advanced-usage.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,98 @@ To use Microsoft EntraID with AMR or ACR, for sure you will need to set up and c
211211

212212
[Use Microsoft Entra](https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-provider-aad?tabs=workforce-configuration)
213213

214+
## HostAndPortMapper
215+
216+
When running Jedis in certain network environments, such as behind a NAT gateway, or within container orchestration systems like Docker or Kubernetes, the host and port that the client needs to connect to might be different from the host and port that the Redis Cluster nodes report. To handle this discrepancy, Jedis provides the `HostAndPortMapper` interface.
217+
218+
This allows you to dynamically map the address reported by a Redis node to a different address that the client can actually reach. You can implement this either by creating a dedicated class or by using a concise lambda expression.
219+
220+
### Example use case: NAT or Docker with different advertised ports
221+
Suppose you run a Redis cluster inside Docker on a remote host.
222+
Inside the cluster config, nodes announce addresses like:
223+
```
224+
172.18.0.2:6379
225+
172.18.0.3:6379
226+
172.18.0.4:6379
227+
```
228+
But externally, you reach them through the host IP with mapped ports:
229+
```
230+
my-redis.example.com:7001
231+
my-redis.example.com:7002
232+
my-redis.example.com:7003
233+
```
234+
### Implementing with a Dedicated Class
235+
236+
You can provide your mapping logic by creating a class that implements the `HostAndPortMapper` interface. This approach is useful for more complex mapping logic or for reusability.
237+
238+
First, define your custom mapper class:
239+
240+
```java
241+
public class DockerNATMapper implements HostAndPortMapper {
242+
243+
// Key: The address reported by Redis (internal).
244+
// Value: The address the client should connect to (external).
245+
private final Map<HostAndPort, HostAndPort> mapping;
246+
247+
public DockerNATMapper(Map<HostAndPort, HostAndPort> mapping) {
248+
this.mapping = mapping;
249+
}
250+
251+
@Override
252+
public HostAndPort getHostAndPort(HostAndPort hostAndPort) {
253+
return mapping.getOrDefault(hostAndPort, hostAndPort);
254+
}
255+
}
256+
```
257+
258+
Then, instantiate this class and pass it to the JedisCluster constructor:
259+
260+
```java
261+
Map<HostAndPort, HostAndPort> nodeMapping = new HashMap<>();
262+
nodeMapping.put(new HostAndPort("172.18.0.2", 6379), new HostAndPort("my-redis.example.com", 7001));
263+
nodeMapping.put(new HostAndPort("172.18.0.3", 6379), new HostAndPort("my-redis.example.com", 7002));
264+
nodeMapping.put(new HostAndPort("172.18.0.4", 6379), new HostAndPort("my-redis.example.com", 7002));
265+
266+
Set<HostAndPort> initialNodes = new HashSet<>();
267+
// seed node
268+
initialNodes.add(new HostAndPort("my-redis.example.com", 7001));
269+
270+
HostAndPortMapper mapper = new DockerNATMapper(nodeMapping);
271+
272+
JedisClientConfig jedisClientConfig = DefaultJedisClientConfig.builder()
273+
.user("myuser")
274+
.password("mypassword")
275+
.hostAndPortMapper(mapper)
276+
.build();
277+
278+
JedisCluster jedisCluster = new JedisCluster(initialNodes, jedisClientConfig);
279+
```
280+
281+
Now, when JedisCluster discovers a node at "172.18.0.2:6379", the mapper will translate it to "localhost:7001" before attempting to connect.
282+
283+
### Implementing with a Lambda Expression
284+
Since HostAndPortMapper is a functional interface (it has only one abstract method), you can also provide the implementation more concisely using a lambda expression. This is often preferred for simpler, inline mapping logic.
285+
286+
```java
287+
Map<HostAndPort, HostAndPort> nodeMapping = new HashMap<>();
288+
nodeMapping.put(new HostAndPort("172.18.0.2", 6379), new HostAndPort("my-redis.example.com", 7001));
289+
nodeMapping.put(new HostAndPort("172.18.0.3", 6379), new HostAndPort("my-redis.example.com", 7002));
290+
nodeMapping.put(new HostAndPort("172.18.0.4", 6379), new HostAndPort("my-redis.example.com", 7002));
291+
292+
Set<HostAndPort> initialNodes = new HashSet<>();
293+
initialNodes.add(new HostAndPort("my-redis.example.com", 7001));
294+
295+
HostAndPortMapper mapper = internalAddress -> nodeMapping.getOrDefault(internalAddress, internalAddress);
296+
297+
JedisClientConfig jedisClientConfig = DefaultJedisClientConfig.builder()
298+
.user("myuser")
299+
.password("mypassword")
300+
.hostAndPortMapper(mapper)
301+
.build();
302+
303+
JedisCluster jedisCluster = new JedisCluster(initialNodes, jedisClientConfig);
304+
```
305+
214306
## Miscellaneous
215307

216308
### A note about String and Binary - what is native?
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
package redis.clients.jedis;
22

3+
/**
4+
* An interface for mapping Redis node addresses.
5+
* <p>
6+
* It is used to translate an advertised server address to one that is reachable by the client,
7+
* especially in network topologies involving NAT or containerization.
8+
*/
9+
@FunctionalInterface
310
public interface HostAndPortMapper {
411

12+
/**
13+
* @param hap The original address from the server.
14+
* @return The translated, reachable address.
15+
*/
516
HostAndPort getHostAndPort(HostAndPort hap);
617
}

0 commit comments

Comments
 (0)