Skip to content

Commit b35a510

Browse files
committed
docs: Improve Javadoc for HostAndPortMapper (#4112)
1 parent 069ea6f commit b35a510

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

docs/advanced-usage.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,69 @@ 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+
### Implementing with a Dedicated Class
221+
222+
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.
223+
224+
First, define your custom mapper class:
225+
226+
```java
227+
public class DockerNATMapper implements HostAndPortMapper {
228+
229+
// Key: The address reported by Redis (internal).
230+
// Value: The address the client should connect to (external).
231+
private final Map<HostAndPort, HostAndPort> mapping;
232+
233+
public DockerNATMapper(Map<HostAndPort, HostAndPort> mapping) {
234+
this.mapping = mapping;
235+
}
236+
237+
@Override
238+
public HostAndPort get(HostAndPort hostAndPort) {
239+
return mapping.getOrDefault(hostAndPort, hostAndPort);
240+
}
241+
}
242+
```
243+
244+
Then, instantiate this class and pass it to the JedisCluster constructor:
245+
246+
```java
247+
Map<HostAndPort, HostAndPort> nodeMapping = new HashMap<>();
248+
nodeMapping.put(new HostAndPort("172.18.0.2", 6379), new HostAndPort("localhost", 7001));
249+
nodeMapping.put(new HostAndPort("172.18.0.3", 6379), new HostAndPort("localhost", 7002));
250+
251+
Set<HostAndPort> initialNodes = new HashSet<>();
252+
initialNodes.add(new HostAndPort("localhost", 7001));
253+
254+
HostAndPortMapper mapper = new DockerNATMapper(nodeMapping);
255+
256+
JedisCluster jedisCluster = new JedisCluster(initialNodes, "myuser", "mypassword", mapper);
257+
```
258+
259+
Now, when JedisCluster discovers a node at "172.18.0.2:6379", the mapper will translate it to "localhost:7001" before attempting to connect.
260+
261+
### Implementing with a Lambda Expression
262+
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.
263+
264+
```java
265+
Map<HostAndPort, HostAndPort> nodeMapping = new HashMap<>();
266+
nodeMapping.put(new HostAndPort("172.18.0.2", 6379), new HostAndPort("localhost", 7001));
267+
nodeMapping.put(new HostAndPort("172.18.0.3", 6379), new HostAndPort("localhost", 7002));
268+
269+
Set<HostAndPort> initialNodes = new HashSet<>();
270+
initialNodes.add(new HostAndPort("localhost", 7001));
271+
272+
HostAndPortMapper mapper = internalAddress -> nodeMapping.getOrDefault(internalAddress, internalAddress);
273+
274+
JedisCluster jedisCluster = new JedisCluster(initialNodes, "myuser", "mypassword", mapper);
275+
```
276+
214277
## Miscellaneous
215278

216279
### A note about String and Binary - what is native?

0 commit comments

Comments
 (0)