@Override public ListenableFuture<ServiceFilterResponse> handleRequest( final ServiceFilterRequest request, final NextServiceFilterCallback nextServiceFilterCallback) { // In this example, if authentication is already in progress we block the request // until authentication is complete to avoid unnecessary authentications as // a result of HTTP status code 401. // If authentication was detected, add the token to the request. waitAndUpdateRequestToken(request); // Send the request down the filter chain // retrying up to 5 times on 401 response codes. ListenableFuture<ServiceFilterResponse> future = null; ServiceFilterResponse response = null; int responseCode = 401; for (int i = 0; (i < 5) && (responseCode == 401); i++) { future = nextServiceFilterCallback.onNext(request); try { response = future.get(); responseCode = response.getStatus().getStatusCode(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { if (e.getCause().getClass() == MobileServiceException.class) { MobileServiceException mEx = (MobileServiceException) e.getCause(); responseCode = mEx.getResponse().getStatus().getStatusCode(); if (responseCode == 401) { // Two simultaneous requests from independent threads could get HTTP status 401. // Protecting against that right here so multiple authentication requests are // not setup to run on the UI thread. // We only want to authenticate once. Requests should just wait and retry // with the new token. if (mAtomicAuthenticatingFlag.compareAndSet(false, true)) { // Authenticate on UI thread runOnUiThread( new Runnable() { @Override public void run() { // Force a token refresh during authentication. authenticate(true); } }); } // Wait for authentication to complete then update the token in the request. waitAndUpdateRequestToken(request); mAtomicAuthenticatingFlag.set(false); } } } } return future; }
private boolean ExceptionIs404NotFound(ExecutionException ex) { MobileServiceException mse = (MobileServiceException) ex.getCause(); if (ex == null) { return false; } int statusCode = mse.getResponse().getStatus().getStatusCode(); if (statusCode != 404) { return false; } return true; }