-
Notifications
You must be signed in to change notification settings - Fork 533
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
feat: Support universe domain for Discovery based libraries #2675
Conversation
/// Otherwise <paramref name="defaultUri"/>. | ||
/// </list> | ||
/// </returns> | ||
protected internal string GetEffectiveUri(string explicitUri, string defaultUri) |
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.
@jskeet this is the method that we'll be using from generated code to calculate the base URI and the batch URI. I'll send that PR out tomorrow.
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.
A few nits, but generally fine.
public static class HttpRequestMessageExtensions | ||
{ | ||
/// <summary> | ||
/// Set's the given key/value pair as a request option. |
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.
Remove apostrophe.
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.
Done, and on the Get's
below as well
/// <summary> | ||
/// Extension methods for <see cref="HttpRequestMessage"/>. | ||
/// </summary> | ||
public static class HttpRequestMessageExtensions |
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.
Rather than making this public, I wonder whether it would be better to have the same code in both projects. That way we can remove it entirely (eventually - it may be a very long time) without affecting the public API at all. We only really want it to be used in our projects, right?
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.
Yep, we only want it in our projects. But it's really in 3 projects that we need this: Google.Apis.Core
, Google.Apis
and Google.Apis.Auth
. And, apart from the triplication, we need to keep it very much in sync because what is set on one side, needs to be equivalently read on the other side.
Plus, the dreprecation path for this is very very clear, with the alternative being "use the .NET provided Options collection instead", which is to say, I think we can deprecate it eventually, and remove after some significant time without a major version.
What do you think?
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.
Actually removing it would then be a binary breaking change, so I'd be nervous about doing that in a minor version.
Given that they need to be kept in sync, how about doing this in one source file that's linked in all three projects? I don't mind it being in the same namespace in all three assemblies.
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 discussed offline. A linked file generates some ambiguity issues in test projects so we are going with 3 identical copies.
// it for the batch endpoint as well. The batch endpoint does not have an | ||
// override mechanism, so we pass explicitUri as null in that case. | ||
|
||
if (explicitUri is not 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.
Possibly convert this all into a conditional ?: operator? (Could even use ?? and then a single ?: operator:
explicitUri ??
(UniverseDomain is not null
? defaultUri?.Replace(DefaultUniverseDomain, UniverseDomain)
: defaultUri)
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.
Yep done
/// <summary> | ||
/// Key for a universe domain in a <see cref="HttpRequestMessage"/> options. | ||
/// </summary> | ||
public const string UniverseDomainKey = "__UniverseDomainKey"; |
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.
Does this need to be public?
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.
Not really, but all the other keys here were public already.
And we don't have to duplicate it in Google.Apis.Auth.
Happy to make it internal or private though, let me know.
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.
Would prefer to "default to internal" in general. We've definitely made more things public here than was probably wise (and the Google.Apis vs Google.Apis.Core split doesn't help; something we should consider addressing if we ever create a new major version) but I think it's worth trying to stop adding extra public things that don't need to be public.
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.
Yep, made internal.
{ | ||
HttpRequestMessage request = new HttpRequestMessage(); | ||
|
||
GoogleCredential credential = GoogleCredential.FromAccessToken("fake_token"); |
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.
Maybe just declare this using type IHttpExecuteInterceptor here, to avoid the "as" below?
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.
(Ditto for other tests)
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.
Uy yes, done
} | ||
|
||
[Fact] | ||
public async Task UniverseDomain_CustomInRequestAndCredential() |
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.
Maybe "DifferentCustomInRequestAndCredential"?
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.
Yep better
if (targetUniverseDomain != credentialUniverseDomain) | ||
{ | ||
throw new InvalidOperationException( | ||
$"The service client universe domain {targetUniverseDomain} does not match the credential universe domain {credentialUniverseDomain}."); |
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.
Indent
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.
Yep, done
60c67de
to
5f8263e
Compare
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.
@jskeet I've addressed or replied to all your comments. Changes are in ordered commits starting with "Address review".
Let me know what you think about the two remaining threads regarding visibility. I prefer them as they are, but that's not a hard preference for either.
public static class HttpRequestMessageExtensions | ||
{ | ||
/// <summary> | ||
/// Set's the given key/value pair as a request option. |
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.
Done, and on the Get's
below as well
/// <summary> | ||
/// Extension methods for <see cref="HttpRequestMessage"/>. | ||
/// </summary> | ||
public static class HttpRequestMessageExtensions |
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.
Yep, we only want it in our projects. But it's really in 3 projects that we need this: Google.Apis.Core
, Google.Apis
and Google.Apis.Auth
. And, apart from the triplication, we need to keep it very much in sync because what is set on one side, needs to be equivalently read on the other side.
Plus, the dreprecation path for this is very very clear, with the alternative being "use the .NET provided Options collection instead", which is to say, I think we can deprecate it eventually, and remove after some significant time without a major version.
What do you think?
// it for the batch endpoint as well. The batch endpoint does not have an | ||
// override mechanism, so we pass explicitUri as null in that case. | ||
|
||
if (explicitUri is not 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.
Yep done
/// <summary> | ||
/// Key for a universe domain in a <see cref="HttpRequestMessage"/> options. | ||
/// </summary> | ||
public const string UniverseDomainKey = "__UniverseDomainKey"; |
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.
Not really, but all the other keys here were public already.
And we don't have to duplicate it in Google.Apis.Auth.
Happy to make it internal or private though, let me know.
{ | ||
HttpRequestMessage request = new HttpRequestMessage(); | ||
|
||
GoogleCredential credential = GoogleCredential.FromAccessToken("fake_token"); |
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.
Uy yes, done
} | ||
|
||
[Fact] | ||
public async Task UniverseDomain_CustomInRequestAndCredential() |
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.
Yep better
if (targetUniverseDomain != credentialUniverseDomain) | ||
{ | ||
throw new InvalidOperationException( | ||
$"The service client universe domain {targetUniverseDomain} does not match the credential universe domain {credentialUniverseDomain}."); |
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.
Yep, done
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.
All "address review" commits look good to me. I have a preference for avoiding the public extension method, but can live with it if you don't want the internal complexity of a linked source file.
5f8263e
to
ab34224
Compare
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.
@jskeet Outstanding visibility concerns addressed in sorted "Address review" commits. PTAL.
(I'll squash most of these before merging)
/// <summary> | ||
/// Key for a universe domain in a <see cref="HttpRequestMessage"/> options. | ||
/// </summary> | ||
public const string UniverseDomainKey = "__UniverseDomainKey"; |
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.
Yep, made internal.
/// <summary> | ||
/// Extension methods for <see cref="HttpRequestMessage"/>. | ||
/// </summary> | ||
public static class HttpRequestMessageExtensions |
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 discussed offline. A linked file generates some ambiguity issues in test projects so we are going with 3 identical copies.
|
||
using System.Net.Http; | ||
|
||
namespace Google.Apis.Util.Extensions; |
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.
Why the ".Extensions" bit? We don't have that for TaskExtensions for example.
Perhaps this was left over from trying to do the link version?
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 intentional, because in tests we already import Google.Apis.Util for other things. So, if we don't put these in specific namespaces, we'd still have the problem of ambiguity.
Note that most the namespaces in Google.Apis.Core are missing the Core bit (except for a few newly added and interal classes) so in Google.Apis.Core we also have Google.Apis.Util, so there I had to do Google.Apis.Core.Util.Extensions.
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.
Righto. Will take a closer look in the morning, but approve now as I'm sure it's fine - feel free to merge.
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.
Thanks!
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.
OK, I know what we can do, we can test the one in Google.Apis instead of the one in Google.Apis.Core and then we can get rid of the Extensions in both. We still need to keep the Google.Apis.Core.Util though (instead of Google.Apis.Util that we normally have in Google.Apis.Core).
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.
Another option is to not use them as extension methods in tests - call them with fully-qualified names (Google.Apis.Utils.HttpRequestMessageExtensions.Xyz()
) so the collision doesn't matter.
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.
Yes, but that still needs us to have the odd Google.Apis.Core.Utils
: it's just Google.Apis.Utils even in Google.Apis.Core, that's the main problem, that in Google.Apis.Core we don't use Core in namespaces. I'm pushing shortly, I've had to use Core or else there's no way to disambiguate, but I was able to drop the Extensions bit.
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.
Pushed:
- The third commit is new, so that everything is normalized.
- And the two Addres Review commits have changed. We still have to use Google.Apis.Core.Utils in Google.Apis.Core even though the norma would have been to use Google.Apis.Utils.
ab34224
to
17f1315
Compare
We don't use Core in Google.Apis.Core, just Google.Apis.
The decision is hidden in HttpRequestMessage extension methods. Note that we had to use the namespace Google.Apis.Core.Utils in the Google.Apis.Core project even though normally it would have been just Google.Apis.Utils.
- The universe domain may be specified through the client service initializer. - A helper method to calculate effective URIs that takes into account the universe domain. This method is to be used by generated code, see googleapis/gapic-generator-csharp#746. - The universe domain is passed as a request option for the credential to validate against when intercepting and before setting the token.
17f1315
to
26e3450
Compare
I've squashed everything into more meaningful commits, I'll merge on green. |
@jskeet as always, one commit at a time. And I've left a note for you to flag the method we are using from generated code.