New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add SSL support to JedisCluster #1550
Conversation
hey @joroda this is really amazing. I'll try to review whenever I have some time. Would love if @xetorthio @HeartSaVioR or @damiri-ts could also take a look. |
@joroda I've been looking at the code to try to understand it. I will outline my analysis of the code here just to make sure I understand it correctly.
It seems that one limitation of this solution, is that the client needs to know all hosts, ports, and TLS ports in the cluster ahead of time. This means that if another node is added to the cluster, the client will not be immediately aware of this. Did I understand this correctly? |
@damiri-ts Your understanding is correct. I'm not sure that there is a way to avoid the client needing to know about all ports/TLS ports ahead of time. However, instead of using a map for these ports, it may be more flexible for the user to provide a Function<int, int> that does the mapping between normal and TLS ports. In the case that the relationship between port and TLS port was easily predictable, the user could provide something like (int p) -> p + 1000 to adapt to nodes being added without having to change code. Please let me know what you think about this. Edit: I've realized that defining anonymous function is something that was only added in Java 8, so that may not be the best option. Alternatively, the client could have the user provide either a Map of the ports or just a integer representing the offset between a port and its TLS port. |
@joroda Providing a port mapping function is a clever idea. I believe that this would be the best solution, short of modifications to the server, because it would allow clients to have immediate knowledge of additional nodes on the cluster, provided some convention for calculating TLS ports from non-TLS ports. Thank you for your contribution. |
@damiri-ts Sounds great. I've just pushed a change to implement this. In order to do this in a way supported by Java 7, I've added the JedisClusterPortMap inteface instead of using Java 8's lambda function feature. Here is the interface: public interface JedisClusterPortMap {
int getSSLPort(int port);
} Users will have to provide an implementation of the interface which could look something like this: JedisClusterPortMap portMap = new JedisClusterPortMap() {
public int getSSLPort(int port) {
return port + 1000;
}
}; Please let me know what you think of this. |
@joroda It looks good to me. I think it's the most flexible and practical solution without server-side changes. |
@damiri-ts @marcosnils Let me know if this needs anything else before it can be merged. |
I'll have a look when I have some time to catch up. Sorry to visit too late. |
@HeartSaVioR Just wanted to check in to see if you've had the chance to take a look at this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
@marcosnils @sazzad16 Please review this. Thanks in advance. |
Looks pretty decent, it would also make sense to provide an address mapper if the IP address is different than the one reported by |
There are no usage of these methods. From redis#1550, it is evident that these are not handy even for ssl operations.
…isting one to fix backwards compatibility issue
# Conflicts: # src/main/java/redis/clients/jedis/JedisCluster.java # src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java # src/main/java/redis/clients/jedis/JedisClusterInfoCache.java # src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java
@sazzad16 I've added the requested changes and attempted to resolve merge conflicts. |
src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java
Outdated
Show resolved
Hide resolved
Assert.assertEquals(CertificateException.class, e.getCause().getCause().getCause().getClass()); | ||
} | ||
|
||
if (jc != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If jc != null
, execution will not reach this point because of previous Assert.fail()
. Put this block in finally and remove following Assert.fail()
. Also, if this is only fail testing, try to hint that in method name (e.g. WithWrongSSLParameters
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to go with connectByIpAddressFailsWithSSLParameters
since in this case, there is not really a right SSLParameters
that will work.
// hostname validation. When closing this Jedis object, the RedisOutputStream in the underlying | ||
// Connection object is null and causes this exception | ||
} | ||
if (jc2 != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If jc2 != null
, execution will not reach this point because of previous Assert.fail()
. Put this block in finally and remove following Assert.fail()
.
InvalidAlgorithmParameterException.class, e.getCause().getCause().getCause().getCause().getClass()); | ||
} | ||
|
||
if (jc != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If jc != null
, execution will not reach this point because of previous Assert.fail()
. Put this block in finally and remove following Assert.fail()
.
Any idea when these changes will be will merged. We badly need these changes. |
Is there any ETA to merge these changes ? |
Maintainers: is there any update? We are considering running our own build of jedis to get this feature. Of course, a release would be easier for us. Is there anything blocking? It has a "ready to merge" tag, so maybe everything is ready to go? |
@johnynek There isn't any approximate date of release. So please use your own build for the time being. Thanks! |
* Add SSL support to JedisCluster * Remove unused imports from SSLJedisClusterTest * Add JedisClusterPortMap interface for mapping between plaintext and SSL ports. * Fix casing in JedisClusterPortMap * Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue * Undo unintended formatting changes. * Improve name of test case in SSLJedisClusterTest * Fix logic for closing JedisCluster objects in SSLJedisClusterTest * Add option to specify mapping between redis and ssl hostnames * Remove unneeded public access modifiers
* Add SSL support to JedisCluster * Remove unused imports from SSLJedisClusterTest * Add JedisClusterPortMap interface for mapping between plaintext and SSL ports. * Fix casing in JedisClusterPortMap * Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue * Undo unintended formatting changes. * Improve name of test case in SSLJedisClusterTest * Fix logic for closing JedisCluster objects in SSLJedisClusterTest * Add option to specify mapping between redis and ssl hostnames * Remove unneeded public access modifiers
Downmerged |
@marcosnils Thank you for merging these PRs 👍 . I was planning to do this weekend :) |
Np. Trying to understand why tests do not pass in travis but they do in my local machine 😕 |
Hmm, that's odd. Because it did pass during merge request. |
@marcosnils Please revert this from 2.9. |
Done. |
I'll revert this PR because of two reasons:
@joroda can you please open the PR again? |
The tests were passing after my latest change to this PR, but that was a while ago so I wonder if other changes to the master branch since then have broken something. I'm not sure I'll have time to make additional changes, but please build off of my contribution if it is helpful. Otherwise, I will probably have time to work on this in a few months. |
@joroda Apologize for the inconveniences and we really appreciate your effort. Would you mind re-opening the PR as-is so we can have a fresh start?. Thx!. |
* Add SSL support to JedisCluster (#1550) * Add SSL support to JedisCluster * Remove unused imports from SSLJedisClusterTest * Add JedisClusterPortMap interface for mapping between plaintext and SSL ports. * Fix casing in JedisClusterPortMap * Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue * Undo unintended formatting changes. * Improve name of test case in SSLJedisClusterTest * Fix logic for closing JedisCluster objects in SSLJedisClusterTest * Add option to specify mapping between redis and ssl hostnames * Remove unneeded public access modifiers * Support for geo RO commands. * Support for geo RO commands. * Support for geo RO commands. * Change _ro to Readonly for better understanding. * Change _ro to Readonly for better understanding Update as per comments * Change _ro to Readonly for better understanding Update as per comments * Minor update. Update commands. https://redis.io/commands/georadius * Update as per comments. * Revert "Add SSL support to JedisCluster (#1550)" This reverts commit 17901ba.
* Add SSL support to JedisCluster (#1550) * Add SSL support to JedisCluster * Remove unused imports from SSLJedisClusterTest * Add JedisClusterPortMap interface for mapping between plaintext and SSL ports. * Fix casing in JedisClusterPortMap * Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue * Undo unintended formatting changes. * Improve name of test case in SSLJedisClusterTest * Fix logic for closing JedisCluster objects in SSLJedisClusterTest * Add option to specify mapping between redis and ssl hostnames * Remove unneeded public access modifiers * Support for geo RO commands. * Support for geo RO commands. * Support for geo RO commands. * Change _ro to Readonly for better understanding. * Change _ro to Readonly for better understanding Update as per comments * Change _ro to Readonly for better understanding Update as per comments * Minor update. Update commands. https://redis.io/commands/georadius * Update as per comments. * Revert "Add SSL support to JedisCluster (#1550)" This reverts commit 17901ba.
Is this solution already part of a Maven release of the jedis artifact? I see here it still lists 2.9.0, which is what I'm currently using and also facing the SSL issue while connecting to AWS Redis Cluster, which is using in-transit encryption, i.e. SSL enabled client required. |
Nope 2.10.0 hasn't been released yet. |
Doesn't seem part of 2.10.0 or 3.0.0. |
…1841) * Add SSL support to JedisCluster (redis#1550) * Add SSL support to JedisCluster * Remove unused imports from SSLJedisClusterTest * Add JedisClusterPortMap interface for mapping between plaintext and SSL ports. * Fix casing in JedisClusterPortMap * Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue * Undo unintended formatting changes. * Improve name of test case in SSLJedisClusterTest * Fix logic for closing JedisCluster objects in SSLJedisClusterTest * Add option to specify mapping between redis and ssl hostnames * Remove unneeded public access modifiers * Support for geo RO commands. * Support for geo RO commands. * Support for geo RO commands. * Change _ro to Readonly for better understanding. * Change _ro to Readonly for better understanding Update as per comments * Change _ro to Readonly for better understanding Update as per comments * Minor update. Update commands. https://redis.io/commands/georadius * Update as per comments. * Revert "Add SSL support to JedisCluster (redis#1550)" This reverts commit 17901ba.
These changes add SSL support to JedisCluster. Tests have also been added. I've tried to solve issue of not being able to get SSL ports from a Redis server by introducing a configuration setting where users can specify a mapping between the ports reported by Redis and the actual SSL ports that should be used. This approach seemed the most flexible.