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.extras.extended.ads_impl.gracefulShutdown; 021 022 023import java.nio.ByteBuffer; 024 025import org.apache.directory.api.asn1.DecoderException; 026import org.apache.directory.api.asn1.EncoderException; 027import org.apache.directory.api.asn1.ber.tlv.BerValue; 028import org.apache.directory.api.asn1.ber.tlv.TLV; 029import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 030import org.apache.directory.api.i18n.I18n; 031import org.apache.directory.api.ldap.codec.api.ExtendedRequestDecorator; 032import org.apache.directory.api.ldap.codec.api.LdapApiService; 033import org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulActionConstants; 034import org.apache.directory.api.ldap.extras.extended.gracefulShutdown.GracefulShutdownRequest; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038 039/** 040 * A Decorator for GracefulShutdownRequests. 041 * 042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 043 */ 044public class GracefulShutdownRequestDecorator extends ExtendedRequestDecorator<GracefulShutdownRequest> 045 implements GracefulShutdownRequest 046{ 047 private static final Logger LOG = LoggerFactory.getLogger( GracefulShutdownRequestDecorator.class ); 048 049 /** Length of the sequence */ 050 private int gracefulSequenceLength; 051 052 private GracefulShutdownRequest gracefulShutdownRequest; 053 054 055 /** 056 * Creates a new instance of GracefulShutdownRequestDecorator. 057 * 058 * @param codec The LDAP Service to use 059 * @param decoratedMessage The GracefulShutdownRequest control to decorate 060 */ 061 public GracefulShutdownRequestDecorator( LdapApiService codec, GracefulShutdownRequest decoratedMessage ) 062 { 063 super( codec, decoratedMessage ); 064 gracefulShutdownRequest = decoratedMessage; 065 } 066 067 068 /** 069 * {@inheritDoc} 070 */ 071 @Override 072 public void setRequestValue( byte[] requestValue ) 073 { 074 GracefulShutdownDecoder decoder = new GracefulShutdownDecoder(); 075 076 try 077 { 078 if ( requestValue != null ) 079 { 080 gracefulShutdownRequest = decoder.decode( requestValue ); 081 082 this.requestValue = new byte[requestValue.length]; 083 System.arraycopy( requestValue, 0, this.requestValue, 0, requestValue.length ); 084 } 085 else 086 { 087 this.requestValue = null; 088 } 089 } 090 catch ( DecoderException e ) 091 { 092 LOG.error( I18n.err( I18n.ERR_04165 ), e ); 093 throw new RuntimeException( e ); 094 } 095 } 096 097 098 /** 099 * {@inheritDoc} 100 */ 101 @Override 102 public byte[] getRequestValue() 103 { 104 if ( requestValue == null ) 105 { 106 try 107 { 108 requestValue = encodeInternal().array(); 109 } 110 catch ( EncoderException e ) 111 { 112 LOG.error( I18n.err( I18n.ERR_04164 ), e ); 113 throw new RuntimeException( e ); 114 } 115 } 116 117 return requestValue; 118 } 119 120 121 /** 122 * {@inheritDoc} 123 */ 124 @Override 125 public int getDelay() 126 { 127 return getDecorated().getDelay(); 128 } 129 130 131 /** 132 * {@inheritDoc} 133 */ 134 @Override 135 public void setDelay( int delay ) 136 { 137 getDecorated().setDelay( delay ); 138 } 139 140 141 /** 142 * {@inheritDoc} 143 */ 144 @Override 145 public int getTimeOffline() 146 { 147 return getDecorated().getTimeOffline(); 148 } 149 150 151 /** 152 * {@inheritDoc} 153 */ 154 @Override 155 public void setTimeOffline( int timeOffline ) 156 { 157 getDecorated().setTimeOffline( timeOffline ); 158 } 159 160 161 /** 162 * Compute the GracefulShutdown length 163 * 164 * <pre> 165 * 0x30 L1 166 * | 167 * +--> [0x02 0x0(1-4) [0..720] ] 168 * +--> [0x80 0x0(1-3) [0..86400] ] 169 * </pre> 170 * L1 will always be < 11. 171 */ 172 /* no qualifier */int computeLengthInternal() 173 { 174 int gracefulLength = 1 + 1; 175 gracefulSequenceLength = 0; 176 177 if ( gracefulShutdownRequest.getTimeOffline() != 0 ) 178 { 179 gracefulSequenceLength += 1 + 1 + BerValue.getNbBytes( gracefulShutdownRequest.getTimeOffline() ); 180 } 181 182 if ( gracefulShutdownRequest.getDelay() != 0 ) 183 { 184 gracefulSequenceLength += 1 + 1 + BerValue.getNbBytes( gracefulShutdownRequest.getDelay() ); 185 } 186 187 return gracefulLength + gracefulSequenceLength; 188 } 189 190 191 /** 192 * Encodes the gracefulShutdown extended operation. 193 * 194 * @return A ByteBuffer that contains the encoded PDU 195 * @throws org.apache.directory.api.asn1.EncoderException If anything goes wrong. 196 */ 197 /* no qualifier */ByteBuffer encodeInternal() throws EncoderException 198 { 199 // Allocate the bytes buffer. 200 ByteBuffer bb = ByteBuffer.allocate( computeLengthInternal() ); 201 202 bb.put( UniversalTag.SEQUENCE.getValue() ); 203 bb.put( TLV.getBytes( gracefulSequenceLength ) ); 204 205 if ( gracefulShutdownRequest.getTimeOffline() != 0 ) 206 { 207 BerValue.encode( bb, gracefulShutdownRequest.getTimeOffline() ); 208 } 209 210 if ( gracefulShutdownRequest.getDelay() != 0 ) 211 { 212 bb.put( ( byte ) GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG ); 213 bb.put( ( byte ) BerValue.getNbBytes( gracefulShutdownRequest.getDelay() ) ); 214 bb.put( BerValue.getBytes( gracefulShutdownRequest.getDelay() ) ); 215 } 216 return bb; 217 } 218 219 220 /** 221 * Return a string representation of the graceful shutdown 222 */ 223 @Override 224 public String toString() 225 { 226 StringBuilder sb = new StringBuilder(); 227 228 sb.append( "Graceful Shutdown extended operation" ); 229 sb.append( " TimeOffline : " ).append( gracefulShutdownRequest.getTimeOffline() ).append( '\n' ); 230 sb.append( " Delay : " ).append( gracefulShutdownRequest.getDelay() ).append( '\n' ); 231 232 return sb.toString(); 233 } 234}