Skip to content
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 backoff mechanism for 429, throw friendly message on REST API error and validate authorization during discovery mode #85

Merged
merged 7 commits into from
Apr 9, 2021

Conversation

karanpanchal-crest
Copy link
Contributor

@karanpanchal-crest karanpanchal-crest commented Apr 4, 2021

Description of change

Since below JIRAs have interdependent code, I have added code for all these JIRAs in this single PR

  • TDL-593: Added backoff mechanism to retry API execution on encountering 429 status code
  • TDL-594: Added support of checking the authentication and authorization of the credentials provided during discovery mode
  • TDL-648: Added custom exceptions to throw friendly message on permission errors and other failure status codes

Manual QA steps

  • Raised 429 status code in the local environment and verified if the function is retrying for this scenario
  • Verified the execution of normal scenario (having status code 200) if it is getting affected because of adding backoff behavior

Risks

Rollback steps

  • revert this branch

@@ -68,7 +68,7 @@ def ensure_credentials_are_valid(config):
XeroClient(config).filter("currencies")

def discover(ctx):
ctx.refresh_credentials()
ctx.check_platform_access()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code added w.r.to TDL-594 (Check authentication and authorization during discovery mode)

self.tenant_id = config['tenant_id']


def check_platform_access(self, config, config_path, check_authentication=True):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code added w.r.to TDL-594 (Check authentication and authorization during discovery mode)

update_config_file(config, config_path)
self.access_token = resp["access_token"]
self.tenant_id = config['tenant_id']
if resp.status_code != 200:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code added w.r.to TDL-594 (Check authentication and authorization during discovery mode)


BASE_URL = "https://api.xero.com/api.xro/2.0"


class XeroError(Exception):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code added w.r.to TDL-648 (Permission Denied error should throw a user friendly message)

api_rate_limit_message = ERROR_CODE_EXCEPTION_MAPPING[429]["message"]
message = "HTTP-error-code: 429, Error: {}. Please retry after {} seconds".format(api_rate_limit_message, resp_headers.get("Retry-After"))
# Handling status code 403 specially since response of API does not contain enough information
elif error_code in (403, 401):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code added w.r.to TDL-648 (Permission Denied error should throw a user friendly message)

@karanpanchal-crest karanpanchal-crest changed the title TDL-593: Adding backoff behavior of 429 errors Add backoff mechanism for 429, throw friendly message on REST API error and validate authorization during discovery mode Apr 6, 2021
"""

@mock.patch('requests.Request', side_effect=mocked_badrequest_400_error)
def test_badrequest_400_error(self, mocked_session, mocked_badrequest_400_error):
Copy link
Contributor Author

@karanpanchal-crest karanpanchal-crest Apr 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test cases to verify TDL-648 (Verifying that different error codes being handled gracefully)



@mock.patch('requests.Request', side_effect=mocked_failed_429_request)
def test_too_many_requests_429_error(self, mocked_session, mocked_failed_429_request):
Copy link
Contributor Author

@karanpanchal-crest karanpanchal-crest Apr 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test cases to verify TDL-593 (Verifying the backoff behavior with Error code 429)


@mock.patch('requests.Session.send', side_effect=mocked_session)
class TestCheckPlatformAccessBehavior(unittest.TestCase):

Copy link
Contributor Author

@karanpanchal-crest karanpanchal-crest Apr 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test cases to verify TDL-594 (Verifying the authentication and authorization behavior during discovery mode)

Copy link
Contributor

@KAllan357 KAllan357 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One adjustment, then this looks good.

json.decoder.JSONDecodeError,
max_tries=3)
@backoff.on_exception(backoff.expo,json.decoder.JSONDecodeError,max_tries=3)
@backoff.on_exception(backoff.expo, XeroTooManyError, max_tries=3, factor=2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exceptions can be combined to form a single backoff statement as a tuple (https://github.com/litl/backoff#backoffon_exception)

ex:

@backoff.on_exception(backoff.expo, (XeroTooManyError, json.decoder.JSONDecodeError), max_tries=3, factor=2)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KAllan357 Incorporated the suggestion

@KAllan357 KAllan357 merged commit 4cc8f3c into master Apr 9, 2021
@KAllan357 KAllan357 deleted the TDL-593-add-backoff-support-for-429-errors branch April 9, 2021 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants