001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.api.ldap.model.message.extended; 021 022 023import org.apache.directory.api.i18n.I18n; 024import org.apache.directory.api.ldap.model.message.ExtendedResponseImpl; 025import org.apache.directory.api.ldap.model.message.ResultCodeEnum; 026import org.apache.directory.api.util.Strings; 027 028 029/** 030 * An extended operation intended for notifying clients of upcoming 031 * disconnection. Here's what <a 032 * href="http://www.faqs.org/rfcs/rfc2251.html">RFC 2251</a> has to say about 033 * it: 034 * 035 * <pre> 036 * Section 4.1.1 (Small snippet on sending NoD) 037 * 038 * If the server receives a PDU from the client in which the LDAPMessage 039 * SEQUENCE tag cannot be recognized, the messageID cannot be parsed, 040 * the tag of the protocolOp is not recognized as a request, or the 041 * encoding structures or lengths of data fields are found to be 042 * incorrect, then the server MUST return the notice of disconnection 043 * described in section 4.4.1, with resultCode protocolError, and 044 * immediately close the connection. In other cases that the server 045 * cannot parse the request received by the client, the server MUST 046 * return an appropriate response to the request, with the resultCode 047 * set to protocolError. 048 * 049 * ... 050 * 051 * 4.4. Unsolicited Notification 052 * 053 * An unsolicited notification is an LDAPMessage sent from the server to 054 * the client which is not in response to any LDAPMessage received by 055 * the server. It is used to signal an extraordinary condition in the 056 * server or in the connection between the client and the server. The 057 * notification is of an advisory nature, and the server will not expect 058 * any response to be returned from the client. 059 * 060 * The unsolicited notification is structured as an LDAPMessage in which 061 * the messageID is 0 and protocolOp is of the extendedResp form. The 062 * responseName field of the ExtendedResponse is present. The LDAPOID 063 * value MUST be unique for this notification, and not be used in any 064 * other situation. 065 * 066 * One unsolicited notification is defined in this document. 067 * 068 * 4.4.1. Notice of Disconnection 069 * 070 * This notification may be used by the server to advise the client that 071 * the server is about to close the connection due to an error 072 * condition. Note that this notification is NOT a response to an 073 * unbind requested by the client: the server MUST follow the procedures 074 * of section 4.3. This notification is intended to assist clients in 075 * distinguishing between an error condition and a transient network 076 * failure. As with a connection close due to network failure, the 077 * client MUST NOT assume that any outstanding requests which modified 078 * the directory have succeeded or failed. 079 * 080 * The responseName is 1.3.6.1.4.1.1466.20036, the response field is 081 * absent, and the resultCode is used to indicate the reason for the 082 * disconnection. 083 * 084 * The following resultCode values are to be used in this notification: 085 * 086 * - protocolError: The server has received data from the client in 087 * which the LDAPMessage structure could not be parsed. 088 * 089 * - strongAuthRequired: The server has detected that an established 090 * underlying security association protecting communication between 091 * the client and server has unexpectedly failed or been compromised. 092 * 093 * - unavailable: This server will stop accepting new connections and 094 * operations on all existing connections, and be unavailable for an 095 * extended period of time. The client may make use of an alternative 096 * server. 097 * 098 * After sending this notice, the server MUST close the connection. 099 * After receiving this notice, the client MUST NOT transmit any further 100 * on the connection, and may abruptly close the connection. 101 * </pre> 102 * 103 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 104 */ 105public final class NoticeOfDisconnect extends ExtendedResponseImpl 106{ 107 /** The OID of the NotiveOfDisconnect extended operation. */ 108 public static final String EXTENSION_OID = "1.3.6.1.4.1.1466.20036"; 109 110 /** The single instance with unavailable result code. */ 111 public static final NoticeOfDisconnect UNAVAILABLE = new NoticeOfDisconnect( ResultCodeEnum.UNAVAILABLE ); 112 113 /** The single instance with protocolError result code. */ 114 public static final NoticeOfDisconnect PROTOCOLERROR = new NoticeOfDisconnect( ResultCodeEnum.PROTOCOL_ERROR ); 115 116 /** The single instance with strongAuthRequired result code. */ 117 public static final NoticeOfDisconnect STRONGAUTHREQUIRED = new NoticeOfDisconnect( 118 ResultCodeEnum.STRONG_AUTH_REQUIRED ); 119 120 121 /** 122 * Creates a new instance of NoticeOfDisconnect. 123 */ 124 private NoticeOfDisconnect( ResultCodeEnum rcode ) 125 { 126 super( 0, EXTENSION_OID ); 127 128 switch ( rcode ) 129 { 130 case UNAVAILABLE: 131 break; 132 133 case PROTOCOL_ERROR: 134 break; 135 136 case STRONG_AUTH_REQUIRED: 137 break; 138 139 default: 140 throw new IllegalArgumentException( I18n.err( I18n.ERR_04166, ResultCodeEnum.UNAVAILABLE, 141 ResultCodeEnum.PROTOCOL_ERROR, ResultCodeEnum.STRONG_AUTH_REQUIRED ) ); 142 } 143 144 super.getLdapResult().setDiagnosticMessage( rcode.toString() + ": The server will disconnect!" ); 145 super.getLdapResult().setMatchedDn( null ); 146 super.getLdapResult().setResultCode( rcode ); 147 } 148 149 150 // ------------------------------------------------------------------------ 151 // ExtendedResponse Interface Method Implementations 152 // ------------------------------------------------------------------------ 153 154 /** 155 * Gets the reponse OID specific encoded response values. 156 * 157 * @return the response specific encoded response values. 158 */ 159 public byte[] getResponse() 160 { 161 return Strings.EMPTY_BYTES; 162 } 163 164 165 /** 166 * Sets the response OID specific encoded response values. 167 * 168 * @param value the response specific encoded response values. 169 */ 170 public void setResponse( byte[] value ) 171 { 172 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04173 ) ); 173 } 174 175 176 /** 177 * Gets the OID uniquely identifying this extended response (a.k.a. its 178 * name). 179 * 180 * @return the OID of the extended response type. 181 */ 182 @Override 183 public String getResponseName() 184 { 185 return EXTENSION_OID; 186 } 187 188 189 /** 190 * Sets the OID uniquely identifying this extended response (a.k.a. its 191 * name). 192 * 193 * @param oid 194 * the OID of the extended response type. 195 */ 196 @Override 197 public void setResponseName( String oid ) 198 { 199 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04168, EXTENSION_OID ) ); 200 } 201 202 203 /** 204 * {@inheritDoc} 205 */ 206 @Override 207 public int hashCode() 208 { 209 int hash = 37; 210 // Seems simple but look at the equals() method ... 211 hash = hash * 17 + getClass().getName().hashCode(); 212 213 return hash; 214 } 215 216 217 /** 218 * {@inheritDoc} 219 */ 220 @Override 221 public boolean equals( Object obj ) 222 { 223 if ( obj == this ) 224 { 225 return true; 226 } 227 228 return obj instanceof NoticeOfDisconnect; 229 } 230}