package org.ovirt.engine.core.bll.adbroker; import java.net.ConnectException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import javax.naming.OperationNotSupportedException; import javax.security.sasl.SaslException; import org.apache.commons.lang.exception.ExceptionUtils; import org.ovirt.engine.core.compat.LogCompat; import org.ovirt.engine.core.compat.LogFactoryCompat; import org.ovirt.engine.core.utils.kerberos.AuthenticationResult; import org.springframework.ldap.AuthenticationException; import org.springframework.ldap.CommunicationException; public class LdapSearchExceptionHandler implements ExceptionHandler<LdapSearchExceptionHandlingResponse> { private static final LogCompat log = LogFactoryCompat.getLog(LdapSearchExceptionHandler.class); @Override public LdapSearchExceptionHandlingResponse handle(Exception e) { LdapSearchExceptionHandlingResponse response = new LdapSearchExceptionHandlingResponse(); if (e instanceof TimeoutException) { // LDAP server didn't respond fast enough handleTimeout(response); } else if (e instanceof ExecutionException) { // thrown by FutureTask and may contain relevant Runtime // Exceptions. Throwable cause = e.getCause(); if (cause != null) { if (cause instanceof EngineDirectoryServiceException) { handleEngineDirectoryServiceException(response, cause); } else if (cause instanceof AuthenticationException) { handleAuthenticationException(response); } else if (cause instanceof CommunicationException) { handleCommunicationException(response, cause); } else if (cause instanceof InterruptedException) { handleInterruptException(response, cause); } else { handleGeneralException(response, e); } } else { for (Throwable throwable : ExceptionUtils.getThrowables(e)) { if ((throwable instanceof SaslException || throwable instanceof ConnectException)) { handleSaslException(response, cause); } else if (throwable instanceof OperationNotSupportedException) { handleOperationException(response, throwable); } } } } return response; } private void handleGeneralException(LdapSearchExceptionHandlingResponse response, Exception e) { response.setTranslatedException(e) .setTryNextServer(true) .setServerScore(Score.LOW); } private void handleSaslException(LdapSearchExceptionHandlingResponse response, Throwable cause) { response.setServerScore(Score.LOW) .setTranslatedException(new EngineDirectoryServiceException(AuthenticationResult.CONNECTION_ERROR, "General connection problem due to " + cause)) .setTryNextServer(true); } private void handleOperationException(LdapSearchExceptionHandlingResponse response, Throwable throwable) { response.setServerScore(Score.HIGH) .setTranslatedException(new EngineDirectoryServiceException(AuthenticationResult.USER_ACCOUNT_DISABLED_OR_LOCKED, throwable)) .setTryNextServer(false); } private void handleInterruptException(LdapSearchExceptionHandlingResponse response, Throwable cause) { response.setServerScore(Score.HIGH) .setTranslatedException((Exception) cause) .setTryNextServer(false); } private void handleCommunicationException(LdapSearchExceptionHandlingResponse response, Throwable cause) { log.error("Error in communicating with LDAP server " + cause.getMessage()); response.setServerScore(Score.LOW).setTryNextServer(true).setTranslatedException((Exception) cause); } private void handleAuthenticationException(LdapSearchExceptionHandlingResponse response) { log.error("Ldap authentication failed. Please check that the login name , password and path are correct. "); EngineDirectoryServiceException ex = new EngineDirectoryServiceException(AuthenticationResult.OTHER); response.setServerScore(Score.HIGH) .setTranslatedException(ex) .setTryNextServer(false); } private void handleEngineDirectoryServiceException(LdapSearchExceptionHandlingResponse response, Throwable cause) { response.setTranslatedException((EngineDirectoryServiceException) cause); switch (((EngineDirectoryServiceException) cause).getResult()) { // connection error or timeout indicates problems with the sever so handling the same. case CONNECTION_ERROR: case CONNECTION_TIMED_OUT: case CLOCK_SKEW_TOO_GREAT: response.setServerScore(Score.LOW).setTryNextServer(true); break; default: response.setServerScore(Score.HIGH).setTryNextServer(false); break; } } private void handleTimeout(LdapSearchExceptionHandlingResponse response) { response.setTryNextServer(true) .setTranslatedException( new EngineDirectoryServiceException(AuthenticationResult.CONNECTION_TIMED_OUT, "Connection to to server has timed out.")) .setServerScore(Score.LOW); } }