public < RET > RET same ( SecuritySetter < HttpURLConnection > ss , Retryable < RET > retryable ) throws APIException , CadiException , LocatorException { RET ret = null ; boolean retry = true ; int retries = 0 ; Rcli < HttpURLConnection > client = retryable . lastClient ( ) ; try { do { // if no previous state, get the best if ( retryable . item ( ) == null ) { retryable . item ( loc . best ( ) ) ; retryable . lastClient = null ; } if ( client == null ) { Item item = retryable . item ( ) ; URI uri = loc . get ( item ) ; if ( uri == null ) { loc . invalidate ( retryable . item ( ) ) ; if ( loc . hasItems ( ) ) { retryable . item ( loc . next ( retryable . item ( ) ) ) ; continue ; } else { throw new LocatorException ( "No clients available for " + loc . toString ( ) ) ; } } client = new HRcli ( this , uri , item , ss ) . connectionTimeout ( connectionTimeout ) . readTimeout ( readTimeout ) . apiVersion ( apiVersion ) ; } else { client . setSecuritySetter ( ss ) ; } retry = false ; try { ret = retryable . code ( client ) ; } catch ( APIException | CadiException e ) { Item item = retryable . item ( ) ; loc . invalidate ( item ) ; retryable . item ( loc . next ( item ) ) ; try { Throwable ec = e . getCause ( ) ; if ( ec instanceof java . net . ConnectException ) { if ( client != null && ++ retries < 2 ) { access . log ( Level . WARN , "Connection refused, trying next available service" ) ; retry = true ; } else { throw new CadiException ( "Connection refused, no more available connections to try" ) ; } } else if ( ec instanceof SSLHandshakeException ) { retryable . item ( null ) ; throw e ; } else if ( ec instanceof SocketException ) { if ( "java.net.SocketException: Connection reset" . equals ( ec . getMessage ( ) ) ) { access . log ( Level . ERROR , ec . getMessage ( ) , " can mean Certificate Expiration or TLS Protocol issues" ) ; } retryable . item ( null ) ; throw e ; } else { retryable . item ( null ) ; throw e ; } } finally { client = null ; } } catch ( ConnectException e ) { Item item = retryable . item ( ) ; loc . invalidate ( item ) ; retryable . item ( loc . next ( item ) ) ; } } while ( retry ) ; } finally { retryable . lastClient = client ; } return ret ; }
Reuse the same service . This is helpful for multiple calls that change service side cached data so that there is not a speed issue .