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 */ 020 package org.apache.directory.shared.ldap.codec.extended.operations.gracefulDisconnect; 021 022 023 import java.nio.ByteBuffer; 024 import java.util.ArrayList; 025 import java.util.List; 026 027 import org.apache.directory.shared.asn1.ber.tlv.TLV; 028 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; 029 import org.apache.directory.shared.asn1.ber.tlv.Value; 030 import org.apache.directory.shared.asn1.codec.EncoderException; 031 import org.apache.directory.shared.ldap.codec.extended.operations.GracefulAction; 032 import org.apache.directory.shared.ldap.codec.extended.operations.GracefulActionConstants; 033 import org.apache.directory.shared.ldap.util.LdapURL; 034 035 036 /** 037 * An extended operation to proceed a graceful disconnect 038 * 039 * <pre> 040 * GracefulDisconnect ::= SEQUENCE 041 * { 042 * timeOffline INTEGER (0..720) DEFAULT 0, 043 * delay [0] INTEGER (0..86400) DEFAULT 0, 044 * replicatedContexts Referral OPTIONAL 045 * } 046 * </pre> 047 * 048 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 049 * @version $Rev: 910150 $, $Date: 2010-02-15 02:37:34 +0100 (Mon, 15 Feb 2010) $, 050 */ 051 public class GracefulDisconnect extends GracefulAction 052 { 053 /** List of the alternate servers to use */ 054 // Two urls will be enough, generally 055 private List<LdapURL> replicatedContexts = new ArrayList<LdapURL>( 2 ); 056 057 /** Length of the sequence */ 058 private int gracefulDisconnectSequenceLength; 059 060 /** Length of the replicated contexts */ 061 private int replicatedContextsLength; 062 063 064 /** 065 * Create a GracefulDisconnect object, with a timeOffline and a delay 066 * 067 * @param timeOffline The time the server will be offline 068 * @param delay The delay before the disconnection 069 */ 070 public GracefulDisconnect( int timeOffline, int delay ) 071 { 072 super( timeOffline, delay ); 073 } 074 075 076 /** 077 * Default constructor. 078 */ 079 public GracefulDisconnect() 080 { 081 super(); 082 } 083 084 085 /** 086 * Get the list of replicated servers 087 * 088 * @return The list of replicated servers 089 */ 090 public List<LdapURL> getReplicatedContexts() 091 { 092 return replicatedContexts; 093 } 094 095 096 /** 097 * Add a new URL of a replicated server 098 * 099 * @param replicatedContext The replictaed server to add. 100 */ 101 public void addReplicatedContexts( LdapURL replicatedContext ) 102 { 103 replicatedContexts.add( replicatedContext ); 104 } 105 106 107 /** 108 * Compute the GracefulDisconnect length 109 * 110 * 0x30 L1 111 * | 112 * +--> [ 0x02 0x0(1-4) [0..720] ] 113 * +--> [ 0x80 0x0(1-3) [0..86400] ] 114 * +--> [ 0x30 L2 115 * | 116 * +--> (0x04 L3 value) + ] 117 */ 118 public int computeLength() 119 { 120 gracefulDisconnectSequenceLength = 0; 121 122 if ( timeOffline != 0 ) 123 { 124 gracefulDisconnectSequenceLength += 1 + 1 + Value.getNbBytes( timeOffline ); 125 } 126 127 if ( delay != 0 ) 128 { 129 gracefulDisconnectSequenceLength += 1 + 1 + Value.getNbBytes( delay ); 130 } 131 132 if ( replicatedContexts.size() > 0 ) 133 { 134 replicatedContextsLength = 0; 135 136 // We may have more than one reference. 137 for ( LdapURL replicatedContext:replicatedContexts ) 138 { 139 int ldapUrlLength = replicatedContext.getNbBytes(); 140 replicatedContextsLength += 1 + TLV.getNbBytes( ldapUrlLength ) + ldapUrlLength; 141 } 142 143 gracefulDisconnectSequenceLength += 1 + TLV.getNbBytes( replicatedContextsLength ) 144 + replicatedContextsLength; 145 } 146 147 return 1 + TLV.getNbBytes( gracefulDisconnectSequenceLength ) + gracefulDisconnectSequenceLength; 148 } 149 150 151 /** 152 * Encodes the gracefulDisconnect extended operation. 153 * 154 * @return A ByteBuffer that contains the encoded PDU 155 * @throws EncoderException If anything goes wrong. 156 */ 157 public ByteBuffer encode() throws EncoderException 158 { 159 // Allocate the bytes buffer. 160 ByteBuffer bb = ByteBuffer.allocate( computeLength() ); 161 162 bb.put( UniversalTag.SEQUENCE_TAG ); 163 bb.put( TLV.getBytes( gracefulDisconnectSequenceLength ) ); 164 165 if ( timeOffline != 0 ) 166 { 167 Value.encode( bb, timeOffline ); 168 } 169 170 if ( delay != 0 ) 171 { 172 bb.put( ( byte ) GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG ); 173 bb.put( ( byte ) TLV.getNbBytes( delay ) ); 174 bb.put( Value.getBytes( delay ) ); 175 } 176 177 if ( replicatedContexts.size() != 0 ) 178 { 179 bb.put( UniversalTag.SEQUENCE_TAG ); 180 bb.put( TLV.getBytes( replicatedContextsLength ) ); 181 182 // We may have more than one reference. 183 for ( LdapURL replicatedContext:replicatedContexts ) 184 { 185 Value.encode( bb, replicatedContext.getBytesReference() ); 186 } 187 } 188 189 return bb; 190 } 191 192 193 /** 194 * Return a string representation of the graceful disconnect 195 */ 196 public String toString() 197 { 198 StringBuffer sb = new StringBuffer(); 199 200 sb.append( "Graceful Disconnect extended operation" ); 201 sb.append( " TimeOffline : " ).append( timeOffline ).append( '\n' ); 202 sb.append( " Delay : " ).append( delay ).append( '\n' ); 203 204 if ( ( replicatedContexts != null) && ( replicatedContexts.size() != 0 ) ) 205 { 206 sb.append( " Replicated contexts :" ); 207 208 // We may have more than one reference. 209 for ( LdapURL url:replicatedContexts ) 210 { 211 sb.append( "\n " ).append( url ); 212 } 213 } 214 215 return sb.toString(); 216 } 217 }