| | |
| | | import java.util.List; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ExecutionException; |
| | | import java.util.concurrent.CopyOnWriteArrayList; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | |
| | | saslContext.evaluateCredentials(result |
| | | .getServerSASLCredentials()); |
| | | } |
| | | catch (SaslException se) |
| | | catch (SaslException e) |
| | | { |
| | | pendingBindOrStartTLS = -1; |
| | | |
| | | Result errorResult = adaptException(se); |
| | | // FIXME: I18N need to have a better error message. |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage( |
| | | "An error occurred during SASL authentication").setCause(e); |
| | | future.handleErrorResult(errorResult); |
| | | return; |
| | | } |
| | |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | future.handleErrorResult(errorResult); |
| | | } |
| | |
| | | */ |
| | | public void handleException(Throwable throwable) |
| | | { |
| | | Result errorResult = adaptException(throwable); |
| | | Result errorResult; |
| | | if(throwable instanceof EOFException) |
| | | { |
| | | // FIXME: Is this the best result code? |
| | | errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_SERVER_DOWN).setCause(throwable); |
| | | } |
| | | else |
| | | { |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_DECODING_ERROR).setCause(throwable); |
| | | } |
| | | connectionErrorOccurred(errorResult); |
| | | } |
| | | |
| | |
| | | |
| | | private boolean isClosed = false; |
| | | |
| | | private final List<ConnectionEventListener> listeners = new LinkedList<ConnectionEventListener>(); |
| | | private final List<ConnectionEventListener> listeners = |
| | | new CopyOnWriteArrayList<ConnectionEventListener>(); |
| | | |
| | | private final AtomicInteger nextMsgID = new AtomicInteger(1); |
| | | |
| | |
| | | } |
| | | catch (IOException e) |
| | | { |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | } |
| | | } |
| | |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | future.handleErrorResult(errorResult); |
| | | } |
| | |
| | | } |
| | | catch (SaslException e) |
| | | { |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: I18N need to have a better error message. |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage( |
| | | "An error occurred during SASL authentication").setCause(e); |
| | | future.handleErrorResult(errorResult); |
| | | return future; |
| | | } |
| | |
| | | else |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | future.handleResult(Responses.newBindResult(ResultCode.PROTOCOL_ERROR) |
| | | future.handleResult(Responses.newBindResult( |
| | | ResultCode.CLIENT_SIDE_AUTH_UNKNOWN) |
| | | .setDiagnosticMessage("Auth type not supported")); |
| | | } |
| | | asn1Writer.flush(); |
| | |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | future.handleErrorResult(errorResult); |
| | | } |
| | |
| | | */ |
| | | public void close() |
| | | { |
| | | close(Requests.newUnbindRequest()); |
| | | close(Requests.newUnbindRequest(), null); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void close(UnbindRequest request) throws NullPointerException |
| | | { |
| | | public void close(UnbindRequest request, String reason) |
| | | throws NullPointerException { |
| | | // FIXME: I18N need to internationalize this message. |
| | | Validator.ensureNotNull(request); |
| | | |
| | | close(request, false, Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED) |
| | | .setDiagnosticMessage("Connection closed by client")); |
| | | close(request, false, |
| | | Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED) |
| | | .setDiagnosticMessage("Connection closed by client" + |
| | | (reason != null ? ": " + reason : ""))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | future.handleErrorResult(errorResult); |
| | | } |
| | |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | future.handleErrorResult(errorResult); |
| | | } |
| | |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | future.handleErrorResult(errorResult); |
| | | } |
| | |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | future.handleErrorResult(errorResult); |
| | | } |
| | |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | future.handleErrorResult(errorResult); |
| | | } |
| | |
| | | { |
| | | pendingRequests.remove(messageID); |
| | | |
| | | Result errorResult = adaptException(e); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | future.handleErrorResult(errorResult); |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | private Result adaptException(Throwable t) |
| | | { |
| | | if (t instanceof ExecutionException) |
| | | { |
| | | ExecutionException e = (ExecutionException) t; |
| | | t = e.getCause(); |
| | | } |
| | | |
| | | Result errorResult; |
| | | |
| | | try |
| | | { |
| | | throw t; |
| | | } |
| | | catch (SaslException e) |
| | | { |
| | | // FIXME: I18N need to have a better error message. |
| | | // FIXME: Is this the best result code? |
| | | errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage( |
| | | "An error occurred during SASL authentication").setCause(e); |
| | | } |
| | | catch (EOFException e) |
| | | { |
| | | // FIXME: I18N need to have a better error message. |
| | | // FIXME: what sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_SERVER_DOWN).setDiagnosticMessage( |
| | | "Connection unexpectedly terminated by server").setCause(e); |
| | | } |
| | | catch (IOException e) |
| | | { |
| | | // FIXME: I18N need to have a better error message. |
| | | // FIXME: what sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage( |
| | | "An error occurred whilst attempting to send a request: " |
| | | + e.toString()).setCause(e); |
| | | } |
| | | catch (Throwable e) |
| | | { |
| | | // FIXME: I18N need to have a better error message. |
| | | // FIXME: Is this the best result code? |
| | | errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage( |
| | | "An unknown error occurred: " + e.toString()).setCause(e); |
| | | } |
| | | |
| | | return errorResult; |
| | | } |
| | | |
| | | |
| | | |
| | | private void close(UnbindRequest unbindRequest, |
| | | boolean isDisconnectNotification, Result reason) |
| | | { |
| | |
| | | { |
| | | for (ConnectionEventListener listener : listeners) |
| | | { |
| | | listener.connectionErrorOccurred(false, ErrorResultException |
| | | .wrap(reason)); |
| | | listener.connectionErrorOccurred(isDisconnectNotification, |
| | | ErrorResultException.wrap(reason)); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | // TODO uncomment if we decide these methods are useful. |
| | | // /** |
| | | // * {@inheritDoc} |
| | | // */ |
| | | // public boolean isClosed() |
| | | // { |
| | | // synchronized (writeLock) |
| | | // { |
| | | // return isClosed; |
| | | // } |
| | | // } |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isClosed() |
| | | { |
| | | synchronized (writeLock) |
| | | { |
| | | return isClosed; |
| | | } |
| | | } |
| | | // |
| | | // |
| | | // |
| | |
| | | sslHandshaker.handshake(reader, writer, sslEngineConfigurator) |
| | | .get(); |
| | | } |
| | | catch (ExecutionException ee) |
| | | { |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_CONNECT_ERROR).setCause(ee.getCause()); |
| | | connectionErrorOccurred(errorResult); |
| | | throw ErrorResultException.wrap(errorResult); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Result result = adaptException(e); |
| | | connectionErrorOccurred(result); |
| | | throw ErrorResultException.wrap(result); |
| | | // FIXME: what other sort of IOExceptions can be thrown? |
| | | // FIXME: Is this the best result code? |
| | | Result errorResult = Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_CONNECT_ERROR).setCause(e); |
| | | connectionErrorOccurred(errorResult); |
| | | throw ErrorResultException.wrap(errorResult); |
| | | } |
| | | } |
| | | |