View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  package org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulShutdown;
21  
22  
23  import java.nio.ByteBuffer;
24  
25  import org.apache.directory.api.asn1.DecoderException;
26  import org.apache.directory.api.asn1.EncoderException;
27  import org.apache.directory.api.asn1.ber.tlv.BerValue;
28  import org.apache.directory.api.asn1.ber.tlv.TLV;
29  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
30  import org.apache.directory.api.i18n.I18n;
31  import org.apache.directory.api.ldap.codec.api.ExtendedRequestDecorator;
32  import org.apache.directory.api.ldap.codec.api.LdapApiService;
33  import org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulActionConstants;
34  import org.apache.directory.api.ldap.extras.extended.gracefulShutdown.GracefulShutdownRequest;
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  
38  
39  /**
40   * A Decorator for GracefulShutdownRequests.
41   *
42   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
43   */
44  public class GracefulShutdownRequestDecorator extends ExtendedRequestDecorator<GracefulShutdownRequest>
45      implements GracefulShutdownRequest
46  {
47      private static final Logger LOG = LoggerFactory.getLogger( GracefulShutdownRequestDecorator.class );
48  
49      /** Length of the sequence */
50      private int gracefulSequenceLength;
51  
52      private GracefulShutdownRequest gracefulShutdownRequest;
53  
54  
55      /**
56       * Creates a new instance of GracefulShutdownRequestDecorator.
57       *
58       * @param codec The LDAP Service to use
59       * @param decoratedMessage The GracefulShutdownRequest control to decorate
60       */
61      public GracefulShutdownRequestDecorator( LdapApiService codec, GracefulShutdownRequest decoratedMessage )
62      {
63          super( codec, decoratedMessage );
64          gracefulShutdownRequest = decoratedMessage;
65      }
66  
67  
68      /**
69       * {@inheritDoc}
70       */
71      @Override
72      public void setRequestValue( byte[] requestValue )
73      {
74          GracefulShutdownDecoder decoder = new GracefulShutdownDecoder();
75  
76          try
77          {
78              if ( requestValue != null )
79              {
80                  gracefulShutdownRequest = decoder.decode( requestValue );
81  
82                  this.requestValue = new byte[requestValue.length];
83                  System.arraycopy( requestValue, 0, this.requestValue, 0, requestValue.length );
84              }
85              else
86              {
87                  this.requestValue = null;
88              }
89          }
90          catch ( DecoderException e )
91          {
92              LOG.error( I18n.err( I18n.ERR_04165 ), e );
93              throw new RuntimeException( e );
94          }
95      }
96  
97  
98      /**
99       * {@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      *   +--&gt; [0x02 0x0(1-4) [0..720] ] 
168      *   +--&gt; [0x80 0x0(1-3) [0..86400] ] 
169      * </pre>  
170      * L1 will always be &lt; 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 }