mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
29.22.2013 53f504f8996e2bf0a08a3915419d5e6a8225ec4c
OPENDJ-832 Leverage the work queue for processing requests received on the HTTP connection handler 

Implemented async search operation.
Added support for canceling tasks.

SdkConnectionAdapter.java: ADDED

CollectClientConnectionsFilter.java:
Hooked the async implementation instead of the synchronous InternalClientConnection.

HTTPClientConnection.java:
Implemented sendResponse(), sendSearchEntry(), sendSearchReference(), disconnect(), getOperationsInProgress(), getOperationInProgress(), removeOperationInProgress(), cancelOperation(), cancelAllOperations(), cancelAllOperationsExcept(), getNumberOfOperations().
Added addOperationInProgress() and isConnectionValid().

procotol*.properties:
Renamed MILD_WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS_166 to MILD_WARN_CLIENT_DISCONNECT_IN_PROGRESS_166.
Removed INFO_HTTP_CONNHANDLER_STARTTLS_NOT_SUPPORTED_1515.
1 files added
11 files modified
638 ■■■■■ changed files
opends/src/messages/messages/protocol.properties 4 ●●● patch | view | raw | blame | history
opends/src/messages/messages/protocol_de.properties 2 ●●● patch | view | raw | blame | history
opends/src/messages/messages/protocol_es.properties 2 ●●● patch | view | raw | blame | history
opends/src/messages/messages/protocol_fr.properties 3 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/protocol_ja.properties 2 ●●● patch | view | raw | blame | history
opends/src/messages/messages/protocol_ko.properties 2 ●●● patch | view | raw | blame | history
opends/src/messages/messages/protocol_zh_CN.properties 2 ●●● patch | view | raw | blame | history
opends/src/messages/messages/protocol_zh_TW.properties 2 ●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/http/CollectClientConnectionsFilter.java 11 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/http/HTTPClientConnection.java 318 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/http/SdkConnectionAdapter.java 283 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java 7 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/protocol.properties
@@ -454,7 +454,7 @@
 unexpected problem was encountered:  %s
INFO_LDAP_CLIENT_GENERIC_NOTICE_OF_DISCONNECTION_165=The Directory Server is \
 closing the connection to this client
MILD_WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS_166=The Directory Server is \
MILD_WARN_CLIENT_DISCONNECT_IN_PROGRESS_166=The Directory Server is \
 currently in the process of closing this client connection
MILD_ERR_LDAP_CLIENT_DECODE_ZERO_BYTE_VALUE_167=The client sent a request to \
 the Directory Server that was an ASN.1 element with a zero-byte value.  This \
@@ -1430,8 +1430,6 @@
MILD_ERR_LDAP_CLIENT_IO_ERROR_DURING_READ_1513=An IO error occurred while \
 reading a request from the client: %s
MILD_ERR_LDAP_CLIENT_IO_ERROR_BEFORE_READ_1514=Connection reset by client
INFO_HTTP_CONNHANDLER_STARTTLS_NOT_SUPPORTED_1515=The HTTP connection handler \
 does not support StartTLS operations
MILD_ERR_CONNHANDLER_CONFIG_CHANGES_REQUIRE_RESTART_1516=The server received \
 configuration changes that require a restart of the %s connection handler \
 to take effect
opends/src/messages/messages/protocol_de.properties
@@ -184,7 +184,7 @@
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_IO_PROBLEM_163=Der Server konnte die LDAP-Nachricht %s (conn=%d, op=%d) nicht an den Client senden, da ein E/A-Problem aufgetreten ist:  %s
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_UNEXPECTED_PROBLEM_164=Der Server konnte die LDAP-Nachricht %s (conn=%d, op=%d) nicht an den Client senden, da ein unerwartetes Problem aufgetreten ist:  %s
INFO_LDAP_CLIENT_GENERIC_NOTICE_OF_DISCONNECTION_165=Directory-Server schlie\u00dft die Verbindung zu diesem Client
MILD_WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS_166=Directory-Server ist derzeit dabei, diese Clientverbindung zu schlie\u00dfen
MILD_WARN_CLIENT_DISCONNECT_IN_PROGRESS_166=Directory-Server ist derzeit dabei, diese Clientverbindung zu schlie\u00dfen
MILD_ERR_LDAP_CLIENT_DECODE_ZERO_BYTE_VALUE_167=Der Client sendete eine Anforderung an Directory-Server, bei der es sich um ein ASN.1-Element mit einem Null-Byte-Wert handelte.  Dies ist m\u00f6glicherweise keine g\u00fcltige LDAP-Nachricht
MILD_ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED_168=Der Client sendete eine Anforderung an Directory-Server mit einer ASN.1-Elementwertl\u00e4nge von %d Bytes.  Da dies die maximal zul\u00e4ssige L\u00e4nge von %d Bytes f\u00fcr Anforderungen \u00fcberschreitet, kann die Verarbeitung f\u00fcr diese Verbindung nicht fortgesetzt werden
MILD_ERR_LDAP_CLIENT_DECODE_INVALID_MULTIBYTE_LENGTH_169=Der Client sendete eine Anforderung an Directory-Server mit einem ASN.1-Element, das mehrere Bytes verwendet, um die Wertl\u00e4nge auszudr\u00fccken.  Die Anforderung zeigte an, dass %d Bytes erforderlich sind, um die L\u00e4nge auszudr\u00fccken, aber dies \u00fcberschreitet die Obergrenze von vier Bytes
opends/src/messages/messages/protocol_es.properties
@@ -184,7 +184,7 @@
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_IO_PROBLEM_163=El servidor no pudo enviar el mensaje LDAP %s (conn=%d, op=%d) al cliente, se detect\u00f3 un problema de E/S:  %s
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_UNEXPECTED_PROBLEM_164=El servidor no pudo enviar el mensaje LDAP %s (conn=%d, op=%d) al cliente, se detect\u00f3 un problema inesperado:  %s
INFO_LDAP_CLIENT_GENERIC_NOTICE_OF_DISCONNECTION_165=Directory Server est\u00e1 cerrando la conexi\u00f3n con este cliente
MILD_WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS_166=Directory Server se encuentra en el proceso de cerrar esta conexi\u00f3n de cliente
MILD_WARN_CLIENT_DISCONNECT_IN_PROGRESS_166=Directory Server se encuentra en el proceso de cerrar esta conexi\u00f3n de cliente
MILD_ERR_LDAP_CLIENT_DECODE_ZERO_BYTE_VALUE_167=El cliente envi\u00f3 una solicitud a Directory Server que era un elemento ASN.1 con un valor de byte cero.  Posiblemente \u00e9ste no pueda ser un mensaje LDAP v\u00e1lido
MILD_ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED_168=El cliente envi\u00f3 una petici\u00f3n a Directory Server con una longitud de valor de elemento ASN.1 de %d bytes.  Esto supera el tama\u00f1o de solicitud m\u00e1ximo de %d bytes, por lo que el procesamiento no puede continuar en esta conexi\u00f3n
MILD_ERR_LDAP_CLIENT_DECODE_INVALID_MULTIBYTE_LENGTH_169=El cliente envi\u00f3 una solicitud a Directory Server con un elemento ASN.1 utilizando varios bytes para expresar la longitud del valor.  La solicitud indic\u00f3 que fueron necesarios %d bytes para expresar la longitud, pero supera el l\u00edmite m\u00e1ximo permitido de cuatro bytes
opends/src/messages/messages/protocol_fr.properties
@@ -184,7 +184,7 @@
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_IO_PROBLEM_163=Le serveur n'a pas pu envoyer le message LDAP %s (conn=%d, op=%d) au client, car un probl\u00e8me d'E/S a \u00e9t\u00e9 d\u00e9tect\u00e9\u00a0: %s
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_UNEXPECTED_PROBLEM_164=Le serveur n'a pas pu envoyer le message LDAP %s (conn=%d, op=%d) au client, car un probl\u00e8me inattendu a \u00e9t\u00e9 d\u00e9tect\u00e9\u00a0: %s
INFO_LDAP_CLIENT_GENERIC_NOTICE_OF_DISCONNECTION_165=Directory Server ferme la connexion \u00e0 ce client
MILD_WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS_166=Directory Server est actuellement en train de fermer cette connexion cliente
MILD_WARN_CLIENT_DISCONNECT_IN_PROGRESS_166=Directory Server est actuellement en train de fermer cette connexion cliente
MILD_ERR_LDAP_CLIENT_DECODE_ZERO_BYTE_VALUE_167=Le client a envoy\u00e9 une demande \u00e0 Directory Server qui \u00e9tait un \u00e9l\u00e9ment ASN.1 avec une valeur \u00e0 octet z\u00e9ro.  Cela ne peut vraiment pas \u00eatre un message LDAP valide
MILD_ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED_168=Le client a envoy\u00e9 une demande \u00e0 Directory Server avec une longueur de valeur d'\u00e9l\u00e9ment ASN.1 de %d octets.  Cela exc\u00e8de la taille maximale de demande autoris\u00e9e de %d octets, le traitement ne peut donc pas continuer sur cette connexion
MILD_ERR_LDAP_CLIENT_DECODE_INVALID_MULTIBYTE_LENGTH_169=Le client a envoy\u00e9 une demande \u00e0 Directory Server avec un \u00e9l\u00e9ment ASN.1 qui utilise plusieurs octets pour exprimer la longueur de la valeur.  La demande indiquait que %d octets \u00e9taient requis pour exprimer la longueur, mais cela exc\u00e8de la limite maximale autoris\u00e9e de quatre octets
@@ -498,5 +498,4 @@
MILD_ERR_ECLN_NO_CONTROL_VALUE_1509=Impossible de d\u00e9coder le contr\u00f4le de notification de journal de modifications d'entr\u00e9e fourni, car il ne poss\u00e8de pas de valeur
MILD_ERR_ECLN_CANNOT_DECODE_VALUE_1510=Impossible de d\u00e9coder le contr\u00f4le de notification de journal de modifications d'entr\u00e9e fourni, car une erreur s'est produite lors de la tentative de d\u00e9codage de sa valeur : %s
SEVERE_ERR_UNEXPECTED_CONNECTION_CLOSURE_1511=La connexion \u00e0 Directory Server a \u00e9t\u00e9 ferm\u00e9e lors de l\u2019attente de la r\u00e9ponse
INFO_HTTP_CONNHANDLER_STARTTLS_NOT_SUPPORTED_1515=Le gestionnaire de connexion HTTP ne permet pas d'utiliser l'op\u00e9ration \u00e9tendue StartTLS.
MILD_ERR_CONNHANDLER_CONFIG_CHANGES_REQUIRE_RESTART_1516=Le serveur a re\u00e7u des changements de configuration qui n\u00e9cessitent de r\u00e9demarrer le gestionnaire de connexion %s pour les appliquer
opends/src/messages/messages/protocol_ja.properties
@@ -184,7 +184,7 @@
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_IO_PROBLEM_163=\u30b5\u30fc\u30d0\u30fc\u306f LDAP \u30e1\u30c3\u30bb\u30fc\u30b8 %s (conn=%d\u3001op=%d) \u3092\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306b\u9001\u4fe1\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u5165\u51fa\u529b\u306e\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f:  %s
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_UNEXPECTED_PROBLEM_164=\u30b5\u30fc\u30d0\u30fc\u306f LDAP \u30e1\u30c3\u30bb\u30fc\u30b8 %s (conn=%d\u3001op=%d) \u3092\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306b\u9001\u4fe1\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u4e88\u671f\u3057\u306a\u3044\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f:  %s
INFO_LDAP_CLIENT_GENERIC_NOTICE_OF_DISCONNECTION_165=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306f\u3053\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3078\u306e\u63a5\u7d9a\u3092\u9589\u3058\u3066\u3044\u307e\u3059
MILD_WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS_166=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306f\u73fe\u5728\u3053\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u63a5\u7d9a\u3092\u9589\u3058\u308b\u51e6\u7406\u3092\u884c\u306a\u3063\u3066\u3044\u307e\u3059
MILD_WARN_CLIENT_DISCONNECT_IN_PROGRESS_166=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306f\u73fe\u5728\u3053\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u63a5\u7d9a\u3092\u9589\u3058\u308b\u51e6\u7406\u3092\u884c\u306a\u3063\u3066\u3044\u307e\u3059
MILD_ERR_LDAP_CLIENT_DECODE_ZERO_BYTE_VALUE_167=\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306f\u30010 \u30d0\u30a4\u30c8\u5024\u3092\u6301\u3064 ASN.1 \u8981\u7d20\u306e\u8981\u6c42\u3092\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306b\u9001\u4fe1\u3057\u307e\u3057\u305f\u3002  \u3053\u308c\u306f\u6709\u52b9\u306a LDAP \u30e1\u30c3\u30bb\u30fc\u30b8\u3067\u306f\u3042\u308a\u3048\u307e\u305b\u3093
MILD_ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED_168=\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306f\u3001ASN.1 \u8981\u7d20\u5024\u9577\u304c %d \u30d0\u30a4\u30c8\u306e\u8981\u6c42\u3092\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306b\u9001\u4fe1\u3057\u307e\u3057\u305f\u3002  \u3053\u308c\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b\u6700\u5927\u8981\u6c42\u30b5\u30a4\u30ba\u306e %d \u30d0\u30a4\u30c8\u3092\u8d85\u904e\u3057\u3066\u3044\u308b\u305f\u3081\u3001\u3053\u306e\u63a5\u7d9a\u3067\u51e6\u7406\u3092\u7d9a\u884c\u3067\u304d\u307e\u305b\u3093
MILD_ERR_LDAP_CLIENT_DECODE_INVALID_MULTIBYTE_LENGTH_169=\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306f\u3001\u5024\u306e\u9577\u3055\u3092\u8868\u73fe\u3059\u308b\u305f\u3081\u306b\u8907\u6570\u30d0\u30a4\u30c8\u3092\u4f7f\u7528\u3059\u308b ASN.1 \u8981\u7d20\u3092\u6301\u3064\u8981\u6c42\u3092\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306b\u9001\u4fe1\u3057\u307e\u3057\u305f\u3002  \u3053\u306e\u8981\u6c42\u306f\u3001\u9577\u3055\u3092\u8868\u73fe\u3059\u308b\u305f\u3081\u306b %d \u30d0\u30a4\u30c8\u5fc5\u8981\u3067\u3042\u308b\u3053\u3068\u3092\u793a\u3057\u3066\u3044\u307e\u3057\u305f\u304c\u3001\u3053\u308c\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b\u6700\u5927\u5236\u9650\u306e 4 \u30d0\u30a4\u30c8\u3092\u8d85\u904e\u3057\u3066\u3044\u307e\u3059
opends/src/messages/messages/protocol_ko.properties
@@ -184,7 +184,7 @@
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_IO_PROBLEM_163=I/O \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0\uc11c LDAP \uba54\uc2dc\uc9c0 %s(conn=%d, op=%d)\uc744(\ub97c) \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0 \ubcf4\ub0bc \uc218 \uc5c6\uc2b5\ub2c8\ub2e4: %s
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_UNEXPECTED_PROBLEM_164=\uc608\uae30\uce58 \uc54a\uc740 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0\uc11c LDAP \uba54\uc2dc\uc9c0 %s(conn=%d, op=%d)\uc744(\ub97c) \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0 \ubcf4\ub0bc \uc218 \uc5c6\uc2b5\ub2c8\ub2e4: %s
INFO_LDAP_CLIENT_GENERIC_NOTICE_OF_DISCONNECTION_165=\ub514\ub809\ud1a0\ub9ac \uc11c\ubc84\uac00 \uc774 \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0 \ub300\ud55c \uc5f0\uacb0\uc744 \ub2eb\uc2b5\ub2c8\ub2e4.
MILD_WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS_166=\ub514\ub809\ud1a0\ub9ac \uc11c\ubc84\uac00 \ud604\uc7ac \uc774 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc5f0\uacb0\uc744 \ub2eb\uace0 \uc788\ub294 \uc911\uc785\ub2c8\ub2e4.
MILD_WARN_CLIENT_DISCONNECT_IN_PROGRESS_166=\ub514\ub809\ud1a0\ub9ac \uc11c\ubc84\uac00 \ud604\uc7ac \uc774 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc5f0\uacb0\uc744 \ub2eb\uace0 \uc788\ub294 \uc911\uc785\ub2c8\ub2e4.
MILD_ERR_LDAP_CLIENT_DECODE_ZERO_BYTE_VALUE_167=\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 ASN.1 \uc694\uc18c\uc778 \ub514\ub809\ud1a0\ub9ac \uc11c\ubc84\uc5d0 0\ubc14\uc774\ud2b8 \uac12\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc694\uccad\uc744 \ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.  \uc774 \uba54\uc2dc\uc9c0\ub294 \uc720\ud6a8\ud55c LDAP \uba54\uc2dc\uc9c0\uac00 \uc544\ub2d0 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
MILD_ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED_168=\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \ub514\ub809\ud1a0\ub9ac \uc11c\ubc84\uc5d0 %d\ubc14\uc774\ud2b8 \uae38\uc774\uc758 ASN.1 \uc694\uc18c \uac12\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc694\uccad\uc744 \ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.  \uc774\ub294 \ud5c8\uc6a9\ub418\ub294 \ucd5c\ub300 \uc694\uccad \ud06c\uae30 %d\ubc14\uc774\ud2b8\ub97c \ucd08\uacfc\ud558\ubbc0\ub85c \uc774 \uc5f0\uacb0\uc5d0\uc11c \ucc98\ub9ac\ub97c \uacc4\uc18d\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
MILD_ERR_LDAP_CLIENT_DECODE_INVALID_MULTIBYTE_LENGTH_169=\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \ub514\ub809\ud1a0\ub9ac \uc11c\ubc84\uc5d0 \uc5ec\ub7ec \ubc14\uc774\ud2b8\ub85c \uac12 \uae38\uc774\ub97c \ud45c\uc2dc\ud558\ub294 ASN.1 \uc694\uc18c\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc694\uccad\uc744 \ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.  \uc694\uccad\uc5d0\ub294 \uae38\uc774\ub97c \ud45c\uc2dc\ud558\ub294 \ub370 %d\ubc14\uc774\ud2b8\uac00 \ud544\uc694\ud55c \uac83\uc73c\ub85c \ub098\ud0c0\ub098\uc9c0\ub9cc \uc774\ub294 \ud5c8\uc6a9\ub418\ub294 \ucd5c\ub300 \uc81c\ud55c\uc778 4\ubc14\uc774\ud2b8\ub97c \ucd08\uacfc\ud569\ub2c8\ub2e4.
opends/src/messages/messages/protocol_zh_CN.properties
@@ -184,7 +184,7 @@
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_IO_PROBLEM_163=\u670d\u52a1\u5668\u65e0\u6cd5\u5c06 LDAP \u6d88\u606f %s\uff08\u8fde\u63a5=%d\uff0c\u64cd\u4f5c=%d\uff09\u53d1\u9001\u5230\u5ba2\u6237\u7aef\uff0c\u56e0\u4e3a\u9047\u5230 I/O \u95ee\u9898: %s
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_UNEXPECTED_PROBLEM_164=\u670d\u52a1\u5668\u65e0\u6cd5\u5c06 LDAP \u6d88\u606f %s\uff08\u8fde\u63a5=%d\uff0c\u64cd\u4f5c=%d\uff09\u53d1\u9001\u5230\u5ba2\u6237\u7aef\uff0c\u56e0\u4e3a\u9047\u5230\u610f\u5916\u95ee\u9898: %s
INFO_LDAP_CLIENT_GENERIC_NOTICE_OF_DISCONNECTION_165=\u76ee\u5f55\u670d\u52a1\u5668\u6b63\u5728\u5173\u95ed\u6b64\u5ba2\u6237\u7aef\u8fde\u63a5
MILD_WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS_166=\u76ee\u5f55\u670d\u52a1\u5668\u5f53\u524d\u6b63\u5728\u5173\u95ed\u6b64\u5ba2\u6237\u7aef\u8fde\u63a5
MILD_WARN_CLIENT_DISCONNECT_IN_PROGRESS_166=\u76ee\u5f55\u670d\u52a1\u5668\u5f53\u524d\u6b63\u5728\u5173\u95ed\u6b64\u5ba2\u6237\u7aef\u8fde\u63a5
MILD_ERR_LDAP_CLIENT_DECODE_ZERO_BYTE_VALUE_167=\u5ba2\u6237\u7aef\u5411\u76ee\u5f55\u670d\u52a1\u5668\u53d1\u9001\u4e86\u4e00\u4e2a\u8bf7\u6c42\uff0c\u8be5\u8bf7\u6c42\u662f\u4e00\u4e2a\u5177\u6709\u96f6\u5b57\u8282\u503c\u7684 ASN.1 \u5143\u7d20\u3002\u8fd9\u4e0d\u53ef\u80fd\u662f\u6709\u6548\u7684 LDAP \u6d88\u606f
MILD_ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED_168=\u5ba2\u6237\u7aef\u5411\u76ee\u5f55\u670d\u52a1\u5668\u53d1\u9001\u4e86\u4e00\u4e2a\u8bf7\u6c42\uff0c\u5176 ASN.1 \u5143\u7d20\u503c\u957f\u5ea6\u4e3a %d \u5b57\u8282\u3002\u8fd9\u8d85\u8fc7\u4e86\u5141\u8bb8\u7684\u6700\u5927\u8bf7\u6c42\u5927\u5c0f\uff08%d \u5b57\u8282\uff09\uff0c\u56e0\u6b64\uff0c\u65e0\u6cd5\u5728\u6b64\u8fde\u63a5\u4e0a\u7ee7\u7eed\u8fdb\u884c\u5904\u7406
MILD_ERR_LDAP_CLIENT_DECODE_INVALID_MULTIBYTE_LENGTH_169=\u5ba2\u6237\u7aef\u5411\u76ee\u5f55\u670d\u52a1\u5668\u53d1\u9001\u4e86\u4e00\u4e2a\u8bf7\u6c42\uff0c\u5176 ASN.1 \u5143\u7d20\u4f7f\u7528\u591a\u5b57\u8282\u8868\u793a\u503c\u957f\u5ea6\u3002\u8be5\u8bf7\u6c42\u6307\u793a\u9700\u8981 %d \u5b57\u8282\u6765\u8868\u793a\u957f\u5ea6\uff0c\u4f46\u8fd9\u8d85\u8fc7\u4e86\u6700\u5927\u5141\u8bb8\u9650\u5236\uff084 \u5b57\u8282\uff09
opends/src/messages/messages/protocol_zh_TW.properties
@@ -184,7 +184,7 @@
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_IO_PROBLEM_163=\u4f3a\u670d\u5668\u7121\u6cd5\u5c07 LDAP \u8a0a\u606f %s (conn=%d\u3001op=%d) \u50b3\u9001\u81f3\u7528\u6236\u7aef\uff0c\u56e0\u70ba\u6709 I/O \u554f\u984c\u767c\u751f: %s
MILD_ERR_LDAP_CLIENT_SEND_MESSAGE_UNEXPECTED_PROBLEM_164=\u4f3a\u670d\u5668\u7121\u6cd5\u5c07 LDAP \u8a0a\u606f %s (conn=%d\u3001op=%d) \u50b3\u9001\u81f3\u7528\u6236\u7aef\uff0c\u56e0\u70ba\u6709\u672a\u9810\u671f\u7684\u554f\u984c\u767c\u751f: %s
INFO_LDAP_CLIENT_GENERIC_NOTICE_OF_DISCONNECTION_165=\u76ee\u9304\u4f3a\u670d\u5668\u6b63\u5728\u7d50\u675f\u6b64\u7528\u6236\u7aef\u7684\u9023\u7dda
MILD_WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS_166=\u76ee\u9304\u4f3a\u670d\u5668\u76ee\u524d\u6b63\u5728\u7d50\u675f\u6b64\u7528\u6236\u7aef\u9023\u7dda
MILD_WARN_CLIENT_DISCONNECT_IN_PROGRESS_166=\u76ee\u9304\u4f3a\u670d\u5668\u76ee\u524d\u6b63\u5728\u7d50\u675f\u6b64\u7528\u6236\u7aef\u9023\u7dda
MILD_ERR_LDAP_CLIENT_DECODE_ZERO_BYTE_VALUE_167=\u7528\u6236\u7aef\u50b3\u9001\u81f3\u76ee\u9304\u4f3a\u670d\u5668\u7684\u8acb\u6c42\u662f\u542b\u6709\u96f6\u4f4d\u5143\u7d44\u503c\u7684 ASN.1 \u5143\u7d20\u3002\u9019\u7121\u6cd5\u505a\u70ba\u6709\u6548\u7684 LDAP \u8a0a\u606f
MILD_ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED_168=\u7528\u6236\u7aef\u5c07 ASN.1 \u5143\u7d20\u503c\u9577\u5ea6\u70ba %d \u4f4d\u5143\u7d44\u7684\u8acb\u6c42\u50b3\u9001\u81f3\u76ee\u9304\u4f3a\u670d\u5668\u3002\u9019\u5df2\u8d85\u904e\u5141\u8a31\u7684\u8acb\u6c42\u5927\u5c0f\u4e0a\u9650 %d \u4f4d\u5143\u7d44\uff0c\u56e0\u6b64\u7121\u6cd5\u7e7c\u7e8c\u8655\u7406\u6b64\u9023\u7dda
MILD_ERR_LDAP_CLIENT_DECODE_INVALID_MULTIBYTE_LENGTH_169=\u7528\u6236\u7aef\u5c07 ASN.1 \u5143\u7d20\u4f7f\u7528\u591a\u4f4d\u5143\u7d44\u8868\u793a\u503c\u9577\u5ea6\u7684\u8acb\u6c42\u50b3\u9001\u81f3\u76ee\u9304\u4f3a\u670d\u5668\u3002\u8a72\u8acb\u6c42\u6307\u51fa\u9700\u8981\u6709 %d \u4f4d\u5143\u7d44\u4ee5\u8868\u793a\u9577\u5ea6\uff0c\u4f46\u9019\u5df2\u8d85\u904e\u56db\u4f4d\u5143\u7d44\u7684\u5141\u8a31\u4e0a\u9650
opends/src/server/org/opends/server/protocols/http/CollectClientConnectionsFilter.java
@@ -42,7 +42,7 @@
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.forgerock.opendj.adapter.server2x.Adapters;
import org.forgerock.opendj.ldap.Connection;
import org.forgerock.opendj.rest2ldap.servlet.Rest2LDAPContextFactory;
import org.opends.messages.Message;
import org.opends.server.admin.std.server.ConnectionHandlerCfg;
@@ -89,7 +89,7 @@
  {
    final Map<ClientConnection, ClientConnection> clientConnections =
        this.connectionHandler.getClientConnectionsMap();
    final ClientConnection clientConnection =
    final HTTPClientConnection clientConnection =
        new HTTPClientConnection(this.connectionHandler, request);
    clientConnections.put(clientConnection, clientConnection);
    try
@@ -131,9 +131,8 @@
        return;
      }
      // TODO JNR handle authentication + send the HTTPClientConnection
      // to Rest2LDAP
      Object result = Adapters.newRootConnection();
      // TODO JNR handle authentication
      Connection connectionAdapter = new SdkConnectionAdapter(clientConnection);
      // WARNING: This action triggers 3-4 others:
      // Set the connection for use with this request on the HttpServletRequest.
@@ -141,7 +140,7 @@
      // AuthenticatedConnectionContext which will in turn ensure Rest2LDAP uses
      // the supplied Connection object
      request.setAttribute(Rest2LDAPContextFactory.ATTRIBUTE_AUTHN_CONNECTION,
          result);
          connectionAdapter);
      // send the request further down the filter chain or pass to servlet
      chain.doFilter(request, response);
opends/src/server/org/opends/server/protocols/http/HTTPClientConnection.java
@@ -26,49 +26,128 @@
 */
package org.opends.server.protocols.http;
import static org.forgerock.opendj.adapter.server2x.Converters.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import javax.servlet.ServletRequest;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.SearchResultHandler;
import org.forgerock.opendj.ldap.responses.Result;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.ConnectionHandler;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.SearchOperation;
import org.opends.server.extensions.TLSCapableConnection;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.CancelRequest;
import org.opends.server.types.CancelResult;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DisconnectReason;
import org.opends.server.types.IntermediateResponse;
import org.opends.server.types.Operation;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchResultReference;
import com.forgerock.opendj.util.AsynchronousFutureResult;
/**
 * This class defines an HTTP client connection, which is a type of client
 * connection that will be accepted by an instance of the HTTP connection
 * handler.
 */
final class HTTPClientConnection extends ClientConnection implements
    TLSCapableConnection
final class HTTPClientConnection extends ClientConnection
{
  // TODO JNR Confirm with Matt that persistent searches are inapplicable to
  // Rest2LDAP.
  // TODO JNR Should I override getIdleTime()?
  // TODO JNR Implement stats
  /**
   * Class grouping together an {@link Operation} and its associated
   * {@link AsynchronousFutureResult} to ensure they are both atomically added
   * and removed from the {@link HTTPClientConnection#operationsInProgress} Map.
   */
  private static final class OperationWithFutureResult
  {
    final Operation operation;
    final AsynchronousFutureResult<Result, SearchResultHandler> futureResult;
    public OperationWithFutureResult(Operation operation,
        AsynchronousFutureResult<Result, SearchResultHandler> futureResult)
    {
      this.operation = operation;
      this.futureResult = futureResult;
    }
  }
  /** The tracer object for the debug logger. */
  private static final DebugTracer TRACER = getTracer();
  /**
   * Official servlet property giving access to the SSF (Security Strength
   * Factor) used to encrypt the current connection.
   */
  private static final String SERVLET_SSF_CONSTANT =
      "javax.servlet.request.key_size";
  /**
   * Indicates whether the Directory Server believes this connection to be valid
   * and available for communication.
   */
  private volatile boolean connectionValid;
  /**
   * Indicates whether this connection is about to be closed. This will be used
   * to prevent accepting new requests while a disconnect is in progress.
   */
  private boolean disconnectRequested;
  /**
   * The Map (messageID => {@link OperationWithFutureResult}) of all operations
   * currently in progress on this connection.
   */
  private final Map<Integer, OperationWithFutureResult> operationsInProgress =
      new ConcurrentHashMap<Integer, OperationWithFutureResult>();
  /**
   * The number of operations performed on this connection. Used to compare with
   * the resource limits of the network group.
   */
  private final AtomicLong operationsPerformed = new AtomicLong(0);
  /**
   * The lock used to provide threadsafe access to the map of operations in
   * progress. This is used when we want to prevent puts on this map while we
   * are removing all operations in progress.
   */
  private final Object opsInProgressLock = new Object();
  /** The connection ID assigned to this connection. */
  private final long connectionID;
  /** The reference to the connection handler that accepted this connection. */
  private final HTTPConnectionHandler connectionHandler;
  /** The servlet request representing this client connection. */
  private final ServletRequest request;
  /** The connection ID assigned to this connection. */
  private final long connectionID;
  /**
   * Constructs an instance of this class.
   *
@@ -179,24 +258,46 @@
  @Override
  public void sendResponse(Operation operation)
  {
    // TODO Auto-generated method stub
    OperationWithFutureResult op =
        this.operationsInProgress.get(operation.getMessageID());
    if (op != null)
    {
      try
      {
        op.futureResult.handleResult(getResponseResult(operation));
      }
      catch (ErrorResultException e)
      {
        op.futureResult.handleErrorResult(e);
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public void sendSearchEntry(SearchOperation searchOperation,
  public void sendSearchEntry(SearchOperation operation,
      SearchResultEntry searchEntry) throws DirectoryException
  {
    // TODO Auto-generated method stub
    OperationWithFutureResult op =
        this.operationsInProgress.get(operation.getMessageID());
    if (op != null)
    {
      op.futureResult.getResultHandler().handleEntry(from(searchEntry));
    }
  }
  /** {@inheritDoc} */
  @Override
  public boolean sendSearchReference(SearchOperation searchOperation,
  public boolean sendSearchReference(SearchOperation operation,
      SearchResultReference searchReference) throws DirectoryException
  {
    // TODO Auto-generated method stub
    return false;
    OperationWithFutureResult op =
        this.operationsInProgress.get(operation.getMessageID());
    if (op != null)
    {
      op.futureResult.getResultHandler().handleReference(from(searchReference));
    }
    return connectionValid;
  }
  /** {@inheritDoc} */
@@ -208,36 +309,128 @@
    return false;
  }
  /** {@inheritDoc} */
  /**
   * {@inheritDoc}
   *
   * @param sendNotification
   *          not used with HTTP.
   */
  @Override
  public void disconnect(DisconnectReason disconnectReason,
      boolean sendNotification, Message message)
  {
    // TODO Auto-generated method stub
    // Set a flag indicating that the connection is being terminated so
    // that no new requests will be accepted. Also cancel all operations
    // in progress.
    synchronized (opsInProgressLock)
    {
      // If we are already in the middle of a disconnect, then don't
      // do anything.
      if (disconnectRequested)
      {
        return;
      }
      disconnectRequested = true;
    }
    // TODO JNR
    // if (keepStats)
    // {
    // statTracker.updateDisconnect();
    // }
    if (connectionID >= 0)
    {
      DirectoryServer.connectionClosed(this);
    }
    // Indicate that this connection is no longer valid.
    connectionValid = false;
    if (message != null)
    {
      MessageBuilder msgBuilder = new MessageBuilder();
      msgBuilder.append(disconnectReason.getClosureMessage());
      msgBuilder.append(": ");
      msgBuilder.append(message);
      cancelAllOperations(new CancelRequest(true, msgBuilder.toMessage()));
    }
    else
    {
      cancelAllOperations(new CancelRequest(true, disconnectReason
          .getClosureMessage()));
    }
    finalizeConnectionInternal();
  }
  /** {@inheritDoc} */
  @Override
  public Collection<Operation> getOperationsInProgress()
  {
    // TODO Auto-generated method stub
    return null;
    Collection<OperationWithFutureResult> values =
        operationsInProgress.values();
    Collection<Operation> results = new ArrayList<Operation>(values.size());
    for (OperationWithFutureResult op : values)
    {
      results.add(op.operation);
    }
    return results;
  }
  /** {@inheritDoc} */
  @Override
  public Operation getOperationInProgress(int messageID)
  {
    // TODO Auto-generated method stub
    OperationWithFutureResult op = operationsInProgress.get(messageID);
    if (op != null)
    {
      return op.operation;
    }
    return null;
  }
  /**
   * Adds the passed in operation to the in progress list along with the
   * associated future.
   *
   * @param operation
   *          the operation to add to the in progress list
   * @param futureResult
   *          the future associated to the operation.
   * @throws DirectoryException
   *           If an error occurs
   */
  void addOperationInProgress(Operation operation,
      AsynchronousFutureResult<Result, SearchResultHandler> futureResult)
      throws DirectoryException
  {
    synchronized (opsInProgressLock)
    {
      // If we're already in the process of disconnecting the client,
      // then reject the operation.
      if (disconnectRequested)
      {
        Message message = WARN_CLIENT_DISCONNECT_IN_PROGRESS.get();
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
      }
      operationsInProgress.put(operation.getMessageID(),
          new OperationWithFutureResult(operation, futureResult));
    }
  }
  /** {@inheritDoc} */
  @Override
  public boolean removeOperationInProgress(int messageID)
  {
    // TODO Auto-generated method stub
    return false;
    final OperationWithFutureResult previousValue =
        operationsInProgress.remove(messageID);
    if (previousValue != null)
    {
      operationsPerformed.incrementAndGet();
    }
    return previousValue != null;
  }
  /** {@inheritDoc} */
@@ -245,15 +438,51 @@
  public CancelResult cancelOperation(int messageID,
      CancelRequest cancelRequest)
  {
    // TODO Auto-generated method stub
    return null;
    OperationWithFutureResult op = operationsInProgress.remove(messageID);
    if (op != null)
    {
      op.futureResult.handleErrorResult(ErrorResultException
          .newErrorResult(org.forgerock.opendj.ldap.ResultCode.CANCELLED));
      return op.operation.cancel(cancelRequest);
    }
    return new CancelResult(ResultCode.NO_SUCH_OPERATION, null);
  }
  /** {@inheritDoc} */
  @Override
  public void cancelAllOperations(CancelRequest cancelRequest)
  {
    // TODO Auto-generated method stub
    synchronized (opsInProgressLock)
    {
      try
      {
        for (OperationWithFutureResult op : operationsInProgress.values())
        {
          try
          {
            op.futureResult.handleErrorResult(ErrorResultException
               .newErrorResult(org.forgerock.opendj.ldap.ResultCode.CANCELLED));
            op.operation.abort(cancelRequest);
          }
          catch (Exception e)
          { // make sure all operations are cancelled, no mattter what
            if (debugEnabled())
            {
              TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
          }
        }
        operationsInProgress.clear();
      }
      catch (Exception e)
      { // TODO JNR should I keep this catch?
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
      }
    }
  }
  /** {@inheritDoc} */
@@ -261,15 +490,25 @@
  public void cancelAllOperationsExcept(CancelRequest cancelRequest,
      int messageID)
  {
    // TODO Auto-generated method stub
    synchronized (opsInProgressLock)
    {
      OperationWithFutureResult toKeep = operationsInProgress.remove(messageID);
      try
      {
        cancelAllOperations(cancelRequest);
      }
      finally
      { // Ensure we always put back this operation
        operationsInProgress.put(messageID, toKeep);
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public long getNumberOfOperations()
  {
    // TODO Auto-generated method stub
    return 0;
    return this.operationsPerformed.get();
  }
  /** {@inheritDoc} */
@@ -310,19 +549,9 @@
  /** {@inheritDoc} */
  @Override
  public boolean prepareTLS(MessageBuilder unavailableReason)
  {
    // TODO JNR add message to mention that this client connection cannot start
    // TLS
    unavailableReason.append(INFO_HTTP_CONNHANDLER_STARTTLS_NOT_SUPPORTED);
    return false;
  }
  /** {@inheritDoc} */
  @Override
  public int getSSF()
  {
    Object attribute = request.getAttribute("javax.servlet.request.key_size");
    Object attribute = request.getAttribute(SERVLET_SSF_CONSTANT);
    if (attribute instanceof Number)
    {
      return ((Number) attribute).intValue();
@@ -333,12 +562,25 @@
      {
        return Integer.parseInt((String) attribute);
      }
      catch (IllegalArgumentException e)
      catch (IllegalArgumentException ignored)
      {
        // TODO tracer debug
        // We cannot do much about it. Just log it.
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ignored);
        }
      }
    }
    return 0;
  }
  /**
   * Returns whether the client connection is valid.
   *
   * @return true if the connection is valid, false otherwise
   */
  boolean isConnectionValid()
  {
    return connectionValid;
  }
}
opends/src/server/org/opends/server/protocols/http/SdkConnectionAdapter.java
New file
@@ -0,0 +1,283 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2013 ForgeRock AS
 */
package org.opends.server.protocols.http;
import static org.forgerock.opendj.adapter.server2x.Converters.*;
import static org.forgerock.opendj.ldap.ByteString.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import java.util.LinkedHashSet;
import org.forgerock.opendj.ldap.AbstractAsynchronousConnection;
import org.forgerock.opendj.ldap.ConnectionEventListener;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.FutureResult;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.opendj.ldap.SearchResultHandler;
import org.forgerock.opendj.ldap.requests.AbandonRequest;
import org.forgerock.opendj.ldap.requests.AddRequest;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.requests.CompareRequest;
import org.forgerock.opendj.ldap.requests.DeleteRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
import org.forgerock.opendj.ldap.requests.ModifyRequest;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.requests.UnbindRequest;
import org.forgerock.opendj.ldap.responses.BindResult;
import org.forgerock.opendj.ldap.responses.CompareResult;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.Result;
import org.opends.server.core.QueueingStrategy;
import org.opends.server.core.SearchOperationBasis;
import org.opends.server.core.WorkQueueStrategy;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import com.forgerock.opendj.util.AsynchronousFutureResult;
/**
 * Adapter class between LDAP SDK's {@link org.forgerock.opendj.ldap.Connection}
 * and OpenDJ server's
 * {@link org.opends.server.protocols.http.HTTPClientConnection}.
 */
public class SdkConnectionAdapter extends AbstractAsynchronousConnection
{
  /** The tracer object for the debug logger. */
  private static final DebugTracer TRACER = getTracer();
  /** The HTTP client connection being "adapted". */
  private final HTTPClientConnection clientConnection;
  /** FIXME: do not use constants. */
  private int messageID;
  /** FIXME: do not use constants. */
  private long operationID;
  /** The queueing strategy used for this connection. */
  private QueueingStrategy queueingStrategy = new WorkQueueStrategy();
  /**
   * Whether this connection has been closed by calling {@link #close()} or
   * {@link #close(UnbindRequest, String)}.
   */
  private boolean isClosed;
  /**
   * Constructor.
   *
   * @param clientConnection
   *          the HTTP client connection being "adapted"
   */
  public SdkConnectionAdapter(HTTPClientConnection clientConnection)
  {
    this.clientConnection = clientConnection;
  }
  /** {@inheritDoc} */
  @Override
  public FutureResult<Void> abandonAsync(AbandonRequest request)
  {
    // TODO Auto-generated method stub
    // for (ConnectionEventListener listener : this.listeners)
    // {
    // listener.
    // }
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public FutureResult<Result> addAsync(AddRequest request,
      IntermediateResponseHandler intermediateResponseHandler,
      ResultHandler<? super Result> resultHandler)
  {
    // AddOperationBasis operation =
    // new AddOperationBasis(clientConnection, operationID, messageID,
    // to(request.getControls()), to(valueOf(request.getName())),
    // to(request.getAllAttributes()));
    // DirectoryServer.enqueueRequest(operation);
    // return StaticUtils.getResponseResult(addOperation);
    // TODO Auto-generated method stub
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public void addConnectionEventListener(ConnectionEventListener listener)
  {
    // not useful so far
  }
  /** {@inheritDoc} */
  @Override
  public FutureResult<BindResult> bindAsync(BindRequest request,
      IntermediateResponseHandler intermediateResponseHandler,
      ResultHandler<? super BindResult> resultHandler)
  {
    // BindOperationBasis operation =
    // new BindOperationBasis(clientConnection, operationID, messageID,
    // to(request.getControls()), "3", to(request.getName()), "",
    // getCredentials(new byte[] {}));
    // TODO Auto-generated method stub
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public void close(UnbindRequest request, String reason)
  {
    isClosed = true;
    // TODO Auto-generated method stub
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public FutureResult<CompareResult> compareAsync(CompareRequest request,
      IntermediateResponseHandler intermediateResponseHandler,
      ResultHandler<? super CompareResult> resultHandler)
  {
    // TODO Auto-generated method stub
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public FutureResult<Result> deleteAsync(DeleteRequest request,
      IntermediateResponseHandler intermediateResponseHandler,
      ResultHandler<? super Result> resultHandler)
  {
    // TODO Auto-generated method stub
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public <R extends ExtendedResult> FutureResult<R> extendedRequestAsync(
      ExtendedRequest<R> request,
      IntermediateResponseHandler intermediateResponseHandler,
      ResultHandler<? super R> resultHandler)
  {
    // TODO Auto-generated method stub
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public boolean isClosed()
  {
    return isClosed;
  }
  /** {@inheritDoc} */
  @Override
  public boolean isValid()
  {
    return this.clientConnection.isConnectionValid();
  }
  /** {@inheritDoc} */
  @Override
  public FutureResult<Result> modifyAsync(ModifyRequest request,
      IntermediateResponseHandler intermediateResponseHandler,
      ResultHandler<? super Result> resultHandler)
  {
    // TODO Auto-generated method stub
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public FutureResult<Result> modifyDNAsync(ModifyDNRequest request,
      IntermediateResponseHandler intermediateResponseHandler,
      ResultHandler<? super Result> resultHandler)
  {
    // TODO Auto-generated method stub
    throw new RuntimeException("Not implemented");
  }
  /** {@inheritDoc} */
  @Override
  public void removeConnectionEventListener(ConnectionEventListener listener)
  {
    // not useful so far
  }
  /** {@inheritDoc} */
  @Override
  public FutureResult<Result> searchAsync(final SearchRequest request,
      final IntermediateResponseHandler intermediateResponseHandler,
      final SearchResultHandler resultHandler)
  {
    // TODO JNR attributes
    LinkedHashSet<String> attributes = null;
    SearchOperationBasis op2 =
        new SearchOperationBasis(clientConnection, operationID, messageID,
            to(request.getControls()), to(valueOf(request.getName())),
            to(request.getScope()), to(request.getDereferenceAliasesPolicy()),
            request.getSizeLimit(), request.getTimeLimit(), request
                .isTypesOnly(), to(request.getFilter()), attributes);
    // TODO JNR set requestID
    final AsynchronousFutureResult<Result, SearchResultHandler> futureResult =
       new AsynchronousFutureResult<Result, SearchResultHandler>(resultHandler);
    try
    {
      clientConnection.addOperationInProgress(op2, futureResult);
      queueingStrategy.enqueueRequest(op2);
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      clientConnection.removeOperationInProgress(messageID);
      // TODO JNR add error message??
      futureResult.handleErrorResult(ErrorResultException.newErrorResult(
          ResultCode.OPERATIONS_ERROR, e));
    }
    return futureResult;
  }
  /** {@inheritDoc} */
  @Override
  public String toString()
  {
    return this.clientConnection.toString();
  }
}
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -1149,6 +1149,10 @@
      {
        // NYI -- Log a message indicating that we couldn't send the
        // notice of disconnection.
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
      }
    }
@@ -1239,8 +1243,7 @@
        // then reject the operation.
        if (disconnectRequested)
        {
          Message message =
            WARN_LDAP_CLIENT_DISCONNECT_IN_PROGRESS.get();
          Message message = WARN_CLIENT_DISCONNECT_IN_PROGRESS.get();
          throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
              message);
        }