api: don't throttle api discovery for listApis command#2894
api: don't throttle api discovery for listApis command#2894yadvr merged 1 commit intoapache:4.11from
Conversation
| for (APIChecker apiChecker : _apiAccessCheckers) { | ||
| try { | ||
| apiChecker.checkAccess(user, apiName); | ||
| if (!"ApiRateLimitServiceImpl".equals(apiChecker.getName())) { |
There was a problem hiding this comment.
you can use something like this.class.getName() or the .getName()... instead of the hard coded string comparison.
There was a problem hiding this comment.
Using the 'ApiRateLimitServiceImpl' class instead of a hard coded string introduces the rate limit plugin module as a dependency to the api discovery module. I didn't think that was a good idea.
| for (APIChecker apiChecker : _apiAccessCheckers) { | ||
| try { | ||
| apiChecker.checkAccess(user, name); | ||
| if (!"ApiRateLimitServiceImpl".equals(apiChecker.getName())) { |
There was a problem hiding this comment.
you can use something like this.class.getName() or the .getName()... instead of the hard coded string comparison.
There was a problem hiding this comment.
Using the 'ApiRateLimitServiceImpl' class instead of a hard coded string introduces the rate limit plugin module as a dependency to the api discovery module. I didn't think that was a good idea.
There was a problem hiding this comment.
What if you used the command class instead? I mean, you are using the "service class", but at this point here you have the command that was used to list the APIs, right? You can use it, and then you do not need to use this hardcoded String.
There was a problem hiding this comment.
@rafaelweingartner Maybe I'm missing something with your suggestion? ListApisCmd is available to the discovery service on the classpath (it's not currently passed into the listApis() method), but I don't see how that helps choose which APIChecker to ignore unless the cmd class gets passed into APIChecker.checkAccess(), which would then introduce an api discovery module dependency on the rate limit plugin module.
It looks like there used to be a separate APILimitChecker interface used for this, but it appears to have been abandoned years ago. I also don't like hard coding names, but the only alternative I saw was a much bigger change that would add risk.
Again, let me know if I misunderstood your suggestion.
There was a problem hiding this comment.
Ok, I am now seeing the big picture. I looking at the code here. I will provide some feedback in another comment
|
@csquire, from your PR description I understood that we should not need/use the API rate limit service. Therefore, we only need to check if the user has access to the API method. Is that it? If that is the case, why don’t we do something different? At To something like: Of course, you need to import the “util” namespace in |
|
yeah, great idea, that looks like a good solution. I'll update the PR. |
|
I took a look at your suggestion @rafaelweingartner but those beans cannot be referenced directly in this context. |
|
ow really? Or, you can implement the |
94cd6c7 to
0a9d45e
Compare
|
With the idea of not injecting the rate limit checker, I tried a different approach by creating a new marker interface and new registry for ACL checkers. Thoughts? |
|
I confess that I really dislike that registry solution that people implemented in ACS. Instead of using Spring life-cycle properly, people decided to create something else. Your solution now works, and it is better than changing the code like it was done in the first attempt. However, I would still prefer something more integrated with Spring life-cycle. Right now I am not able to think in something to enable us to work around this problem. Therefore, I am inclined to say that this last proposal is fine. |
| @@ -0,0 +1,7 @@ | |||
| package org.apache.cloudstack.acl; | |||
There was a problem hiding this comment.
You missed the license header here
0a9d45e to
dcb9d23
Compare
|
@blueorangutan package |
|
@rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress. |
|
Packaging result: ✔centos6 ✔centos7 ✔debian. JID-2482 |
|
@blueorangutan test |
|
@rhtyd a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests |
|
Trillian test result (tid-3246)
|
|
@rhtyd is this ready? |
|
Let me test this tomorrow @DaanHoogland |
Description
Users reported that they weren't getting all apis listed in cloudmonkey when running a
sync. After some debugging, I found that the problem is that theApiDiscoveryServiceis callingApiRateLimitServiceImpl.checkAccess(), so the results of the listApis command are being truncated because Cloudstack believes the user has exceeded their API throttling rate.I enabled throttling with a 25 request per second limit. I then created a test role with only
list*permissions and assigned it to a test user. When this user callslistApis, they will typically receive anywhere from 15-18 results. Checking the logs, you seeThe given user has reached his/her account api limit, please retry after 218 ms..I raised the limit to 200 requests per second, restarted the management server and tried again. This time I got 143 results and no log messages about the user being throttled.
Types of changes
GitHub Issue/PRs
Fixes: #2842
Screenshots (if appropriate):
How Has This Been Tested?
Updated the appropriate unit tests to verify the ApiRateLimitService is not longer called when discovering APIs.
Checklist:
Testing