v2client/src/main/java/com/yubico/client/v2/VerificationRequester.java
public VerificationResponse fetch(List<String> urls, String userAgent) throws YubicoVerificationException {
	    List<Future<VerificationResponse>> tasks = new ArrayList<Future<VerificationResponse>>();
	    for(String url : urls) {
			tasks.add(completionService.submit(createTask(userAgent, url)));
	    }
	    VerificationResponse response = null;
		try {
			int tasksDone = 0;
			Throwable savedException = null;
			Future<VerificationResponse> futureResponse = completionService.poll(1L, MINUTES);
			while(futureResponse != null) {
				try {
					tasksDone++;
					tasks.remove(futureResponse);
					response = futureResponse.get();
					/**
					 * If the response returned is REPLAYED_REQUEST keep looking at responses
					 * and hope we get something else. REPLAYED_REQUEST will be returned if a
					 * validation server got sync before it parsed our query (otp and nonce is
					 * the same).
					 * @see https://forum.yubico.com/viewtopic21be.html
					 *
					 * Also if the response is BACKEND_ERROR, keep looking for a server that
					 * sends a valid response
					 * @see https://github.com/Yubico/yubico-java-client/issues/12
					 */
					if(!response.getStatus().equals(REPLAYED_REQUEST) && !response.getStatus().equals(BACKEND_ERROR)) {
						break;
					}
				} catch (CancellationException ignored) {
					// this would be thrown by old cancelled calls.
					tasksDone--;
				} catch (ExecutionException e) {
					// tuck the real exception away and use it if we don't get any valid answers.
					savedException = e.getCause();
				}
				if(tasksDone >= urls.size()) {
					break;
				}
				futureResponse = completionService.poll(1L, MINUTES);
			}
			if(futureResponse == null || response == null) {
				if(savedException != null) {
					throw new YubicoVerificationException(
							"Exception while executing validation.", savedException);
				} else {
					throw new YubicoVerificationException("Validation timeout.");
				}
			}
		} catch (InterruptedException e) {
			throw new YubicoVerificationException("Validation interrupted.", e);
		}
	    
		for(Future<VerificationResponse> task : tasks) {
			task.cancel(true);
		}
		
	    return response;
	}
public VerificationResponse fetch(List<String> urls, String userAgent) throws YubicoVerificationException {
	    List<Future<VerificationResponse>> tasks = new ArrayList<Future<VerificationResponse>>();
	    for(String url : urls) {
			tasks.add(completionService.submit(createTask(userAgent, url)));
	    }
	    VerificationResponse response = null;
		try {
			int tasksDone = 0;
			Throwable savedException = null;
			Future<VerificationResponse> futureResponse = completionService.poll(1L, MINUTES);
			while(futureResponse != null) {
				try {
					tasksDone++;
					tasks.remove(futureResponse);
					response = futureResponse.get();
					/**
					 * If the response returned is REPLAYED_REQUEST keep looking at responses
					 * and hope we get something else. REPLAYED_REQUEST will be returned if a
					 * validation server got sync before it parsed our query (otp and nonce is
					 * the same).
					 * @see https://forum.yubico.com/viewtopic21be.html
					 *
					 * Also if the response is BACKEND_ERROR, keep looking for a server that
					 * sends a valid response
					 * @see https://github.com/Yubico/yubico-java-client/issues/12
					 */
					if(!response.getStatus().equals(REPLAYED_REQUEST) && !response.getStatus().equals(BACKEND_ERROR)) {
						break;
					}
				} catch (CancellationException ignored) {
					// this would be thrown by old cancelled calls.
					tasksDone--;
				} catch (ExecutionException e) {
					// tuck the real exception away and use it if we don't get any valid answers.
					savedException = e.getCause();
				}
				if(tasksDone >= urls.size()) {
					break;
				}
				futureResponse = completionService.poll(1L, MINUTES);
			}
			if(futureResponse == null || response == null) {
				if(savedException != null) {
					throw new YubicoVerificationException(
							"Exception while executing validation.", savedException);
				} else {
					throw new YubicoVerificationException("Validation timeout.");
				}
			}
		} catch (InterruptedException e) {
			throw new YubicoVerificationException("Validation interrupted.", e);
		}
	    
		for(Future<VerificationResponse> task : tasks) {
			task.cancel(true);
		}
		
	    return response;
	}
public VerificationResponse fetch ( List < String > urls , String userAgent ) throws YubicoVerificationException { List < Future < VerificationResponse >> tasks = new ArrayList < Future < VerificationResponse > > ( ) ; for ( String url : urls ) { tasks . add ( completionService . submit ( createTask ( userAgent , url ) ) ) ; } VerificationResponse response = null ; try { int tasksDone = 0 ; Throwable savedException = null ; Future < VerificationResponse > futureResponse = completionService . poll ( 1L , MINUTES ) ; while ( futureResponse != null ) { try { tasksDone ++ ; tasks . remove ( futureResponse ) ; response = futureResponse . get ( ) ; /**
					 * If the response returned is REPLAYED_REQUEST keep looking at responses
					 * and hope we get something else. REPLAYED_REQUEST will be returned if a
					 * validation server got sync before it parsed our query (otp and nonce is
					 * the same).
					 * @see https://forum.yubico.com/viewtopic21be.html
					 *
					 * Also if the response is BACKEND_ERROR, keep looking for a server that
					 * sends a valid response
					 * @see https://github.com/Yubico/yubico-java-client/issues/12
					 */ if ( ! response . getStatus ( ) . equals ( REPLAYED_REQUEST ) && ! response . getStatus ( ) . equals ( BACKEND_ERROR ) ) { break ; } } catch ( CancellationException ignored ) { // this would be thrown by old cancelled calls. tasksDone -- ; } catch ( ExecutionException e ) { // tuck the real exception away and use it if we don't get any valid answers. savedException = e . getCause ( ) ; } if ( tasksDone >= urls . size ( ) ) { break ; } futureResponse = completionService . poll ( 1L , MINUTES ) ; } if ( futureResponse == null || response == null ) { if ( savedException != null ) { throw new YubicoVerificationException ( "Exception while executing validation." , savedException ) ; } else { throw new YubicoVerificationException ( "Validation timeout." ) ; } } } catch ( InterruptedException e ) { throw new YubicoVerificationException ( "Validation interrupted." , e ) ; } for ( Future < VerificationResponse > task : tasks ) { task . cancel ( true ) ; } return response ; }
Fires off a validation request to each url in the list, returning the first one
that is not {@link ResponseStatus#REPLAYED_REQUEST}

@param urls a list of validation urls to be contacted
@param userAgent userAgent to send in request, if null one will be generated
@return {@link VerificationResponse} object from the first server response that is not
{@link ResponseStatus#REPLAYED_REQUEST}
@throws com.yubico.client.v2.exceptions.YubicoVerificationException if validation fails on all urls
Fires off a validation request to each url in the list returning the first one that is not { @link ResponseStatus#REPLAYED_REQUEST }