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
L74: Java Channel Credentials #198
Conversation
@ZhenLian FYI |
* Author(s): [Eric Anderson](https://github.com/ejona86) | ||
* Approver: sanjaypujare | ||
* Status: In Review {Draft, In Review, Ready for Implementation, Implemented} | ||
* Implemented in: <language, ...> |
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.
Put Java here?
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.
It's not implemented yet, so I was leaving it as-is. I expected to update the gRFC after adding it to grpc-java to update this line. I'd also update the "Implementation" section to say which version it was added to.
We don't actually gain anything by it, as EnumSet doesn't have any methods of its own. It doesn't really hurt anything if someone uses something other than EnumSet, and swapping to plain set resolves the minor oddity that the return value (Set) differed from the input (EnumSet).
channel = ManagedChannelBuilder.forAddress("example.com", 443) | ||
.build(); | ||
// the user would now: | ||
channel = Grpc.newChannelBuilder("example.com", new TlsChannelCredentials()) |
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've sent out the changes for this proposal in grpc/grpc-java#7294 .
One thing came out of that when using the unstable ChannelCredentials as provided by the transports: they won't have constructors. I don't care too much about users that use the classes in io.grpc.netty or io.grpc.okhttp directly, since they are few and can "deal with it." But it is a bigger concern for more user-facing things like GoogleDefaultChannelCredentials. We have a few of those today and will get more, like XdsChannelCredentials. That could cause "normal users" to see a mix of both construction styles.
API design review, just talking about whether to have
(2) has more complexity, via an extra level of indirection, but is clear. (1) suffices, but has some awkwardness. @carl-mastrangelo, do you want to provide a vote? We all could accept either way (1 or 2), but had different preferences. |
I should also mention, from the API review:
So those were things considered, but did not settle on them. |
My leaning is more towards (2). I didnt have any other feedback at this point. |
I made the changes for approach (1), which is a prerequisite for (2) anyway. I thought I had been convinced to go with approach (2), and I started with making the changes for (2). But it seemed to mostly add confusion and goo. The documentation in particular had to become more precise in a way that seemed unhelpful. And users were going to need to "see" the Config object places and know to just ignore it. I'm going to try again tomorrow with the changes to (2) and see how it compares a bit more directly. |
Server side can just declare it mirrors client-side, and it is more fleshed out than it was earlier
…tials, SslSocketFactoryChannelCredentials These are necessary to allow migration from existing APIs.
* Freshly-constructed credentials should be returned as {@code | ||
* ChannelCredentials} instead of a concrete type to encourage this pattern. | ||
* Concrete types would only be used after {@code instanceof} checks (which must | ||
* consider {@code ChoiceChannelCredentials}!). |
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.
We are not hiding concrete types (like ChoiceChannelCredentials
or CompositeChannelCredentials
) but expect users to do instanceof
and a type-cast to be able to use methods like getChannelCredentials()
of CompositeChannelCredentials
(for example). How does it support the view that "concrete type should not be relevant to API users and may be an implementation decision"?
Wouldn't it then be better for the create()
methods to return the actual public concrete type, but making sure that most of the functionality is at the ChannelCredentials
level and we only expose the minimum necessary functionality in the exposed concrete type?
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.
Most users don't need to call any methods on the credentials. They just 1) create them and 2) pass them around. The transports are the main thing that needs to call methods on the credentials.
Wouldn't it then be better for the create() methods to return the actual public concrete type
Better in what way?
but making sure that most of the functionality is at the ChannelCredentials level and we only expose the minimum necessary functionality in the exposed concrete type?
I don't understand what that would look like. Could you provide a sketch of what ChannelCredentials would look like in that approach?
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.
Wouldn't it then be better for the create() methods to return the actual public concrete type
Better in what way?
Compared to what was described in the original text "...Concrete types would only be used after {@code instanceof} checks..."
So with the current proposal one would do:
ChannelCredentials channelCreds = ChoiceChannelCredentials.create(...);
...
// somewhere later in the code
if (channelCreds instanceof ChoiceChannelCredentials) {
ChoiceChannelCredentials choiceChannelCreds = (ChoiceChannelCredentials)channelCreds;
// do something with choiceChannelCreds
}
Whereas if create
returned the actual concrete type you wouldn't need the check and the cast:
ChoiceChannelCredentials choiceChannelCreds = ChoiceChannelCredentials.create(...);
...
// somewhere later in the code
// do something with choiceChannelCreds
All I am saying is that exposing/making public concrete subclasses but not have create
return them looks a little inconsistent but I do understand the argument about encouraging the pattern.
but making sure that most of the functionality is at the ChannelCredentials level and we only expose the minimum necessary functionality in the exposed concrete type?
I don't understand what that would look like. Could you provide a sketch of what ChannelCredentials would look like in that approach?
Nothing different from what is currently being proposed. As you said users would mostly create creds and pass them around because the ChannelCredentials
interface/functionality should work for most cases.
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.
There is a very strong producer/consumer split with this API. The producer doesn't have any need to look at the configuration; it provided it. The consumer is what needs to look at the configuration, and if it only supports one specific credential type that sort of defeats the purpose. So I don't see your example as reflecting any actual use case for this API.
As you said users would mostly create creds and pass them around because the ChannelCredentials interface/functionality should work for most cases.
No, I don't understand what configuration you think should be within ChannelCredentials.
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
Take special note of how ManagedChannelBuilders are created.