Closed kvmw closed 2 years ago
Can you provide some additional information?
Thanks
Here is the client config:
@Configuration
@EnableConfigurationProperties({UaaClientProperties.class, AppUriProperties.class})
class ServiceInstanceBindingConfiguration {
@Bean
UaaBackingAppCredentialsClient uaaBackingAppUserClient(ReactorUaaClient uaaClient) {
return new UaaBackingAppCredentialsClient(uaaClient);
}
@Bean
ClientCredentialsGrantTokenProvider bindingTokenProvider(UaaClientProperties uaaProperties) {
return ClientCredentialsGrantTokenProvider.builder()
.clientId(uaaProperties.getClientId())
.clientSecret(uaaProperties.getClientSecret())
.build();
}
@Bean
ReactorUaaClient bindingUaaClient(ConnectionContext connectionContext,
ClientCredentialsGrantTokenProvider tokenProvider) {
return ReactorUaaClient.builder()
.connectionContext(connectionContext)
.tokenProvider(tokenProvider)
.build();
}
@Bean
ConnectionContext uaaConnectionContext(UaaClientProperties uaaProperties) {
return DefaultConnectionContext.builder()
.rootProvider(new RootProvider() {
@Override
public Mono<String> getRoot(ConnectionContext connectionContext) {
return Mono.just(uaaProperties.getUaaUri());
}
@Override
public Mono<String> getRoot(String key, ConnectionContext connectionContext) {
return Mono.just(uaaProperties.getUaaUri());
}
})
.apiHost(uaaProperties.getHost())
.secure(uaaProperties.getScheme().startsWith("https"))
.port(Integer.parseInt(uaaProperties.getPort()))
.build();
}
}
Tokens have the life time of 1 day. so the client needs to renew them every day.
I noticed that there is only one log message about token renewal: Negotiating using refresh token
in 5 days logs.
given that the default retry is 5, i don't understand why retry is not happening.
Hi @dmikusa-pivotal Please let us know if there is any update on this issue. This is related to JIRA https://pivotal-io.atlassian.net/browse/SCS-49 which we opened few months ago. Currently customer is still waiting for a fix so far. Thanks.
@kvmw I've merged a PR which fixes a comparison check between a 401 status and the response received - we are hoping this is the cause. Since you can reproduce the issue, could you try testing with the latest builds of the operations and reactor libs?
@pivotal-david-osullivan, Thanks for the update. As far as I know, only one client has reported this issue. I've not been able to reproduce this issue myself. I'm afraid the only way to try this fix in the client environment is by releasing a new version of SCS ( sporing cloud services) which requires new release of the library.
@pivotal-david-osullivan, The only way i could reproduce the issue in my local env. was by providing different reason message for 401 status code from the mock UAA server. So if the UAA server returns anything other than Unauthorized
reason message for 401 code, the current cf-java-client fails to compare it properly.
The code you've merged fixes this issue. But I don't have any way to verify if UAA has ever returned a 401 code with a custom reason message in our production env.
Thanks for confirming @kvmw! We were wondering if something in the user's environment could be interfering with the response to create the scenario that is only being seen in this case?
@dmikusa-pivotal , Apparently this is the default behaviour of uaa. I've cloned the uaa repo and ran it locally. when the response is 401 the reason-phrase is empty (not Unauthorized).
By changing the UAA access-token lifetime to 60 seconds, i can easily reproduce the issue now with following code:
GetClientRequest request = GetClientRequest.builder().clientId("app").build();
System.out.println(client.clients().get(request).block().getName()); // Successful call, first call with new access token.
Thread.sleep(30 * 1000);
System.out.println(client.clients().get(request).block().getName()); // Successful call, access token still is valid.
Thread.sleep(31 * 1000);
System.out.println(client.clients().get(request).block().getName()); // Fails with 401. because access token has been expired after 61 seconds. There is not attempt to refresh the token.
Now the more important question is: why only one of our customers complaining about this issue. Given above behaviour all of them should have seen such issue.
Found this in spring-boot repo: https://github.com/spring-projects/spring-boot/issues/6548
Apparently tomcat 8.5 has stoped sending the reason phrase : https://bz.apache.org/bugzilla/show_bug.cgi?id=60362
Again, this does not answer why more clients are not complaining about this issue.
Again, this does not answer why more clients are not complaining about this issue.
I might have one possible reason: Most consumers of the library often have only a short runtime, i.e. below the exp
's timestamp. 24hrs is a lot! That is why they always use the same JWT, never have to refresh and hence never run into this issue. Only applications (such as Promregator) run typically for weeks or months and therefore have to refresh their tokens.
@pivotal-david-osullivan Is the PR that you are referring to in https://github.com/cloudfoundry/cf-java-client/issues/1130#issuecomment-1041854109 the PR at #1136? Background to this is that I would like to try out your assumed patch hoping to fix https://github.com/promregator/promregator/issues/218.
If yes, then it is already released with 5.7.0
and consumption would be rather easy for me...
If no, things would become tricky...
Thanks for the info!
@eaglerainbow - Sorry, we should have followed up and closed out this issue. #1136 should be the fix for this issue, and yes, that is in 5.7.0.
The environment where this was reported initially only seldom hit the issue. Due to that, it's a little difficult to confirm 100% that the issue is resolved because it would probably take months to definitively confirm, but confidence in the solution is high.
The change uses .equals()
instead of ==
in a comparison. The item being compared is an object, so it should really be using .equals()
, otherwise it's just comparing the two references are the same. We believe that ==
check did work in some cases because often the library will use a static instance to represent the http status. Thus when a comparison is done it's comparing two references to the same static instance of the object and ==
would be true. In some cases, like if the reason phrase does not match the expected reason phrase then the library will create a new instance an http status object. This would then be a different instance and not match with ==
when compared to the static instance. Using .equals()
works because the object comparison is done on the http status code which does match, regardless of the reason phrase.
Hope that helps! I'm going to close this out, but feel free to reopen if you use 5.7.0 and are still seeing issues.
Thanks for the verbose response! I have bumped Promregator with version 0.10.2 to cf-java-client 5.7.0. Also for us, it's non-trivial to trigger the issue to happen. However, with https://github.com/promregator/promregator/issues/218#issuecomment-1085189699 we will try to do so. In case we don't report back here, consider this issue solved. (BTW: As I am not a member of this repository, I do not have authorities to reopen issues).
(BTW: As I am not a member of this repository, I do not have authorities to reopen issues).
Oh, ok. Good to know. I thought users could do that. Thanks
Looking at
Operator.java
in cf-java-client source code, I see that in case of 401 responses, the reactor-client retries the requests with new token. So there should be noInvalidAccessToken
(401) thrown out of the library. But as you can see in the below stack trace, we are catching such exceptions, frequently, in our code.cf-java-client v4.16.0
stack trace: