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   *    https://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 org.apache.directory.api.asn1.DecoderException;
24  import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
25  import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
26  import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
27  import org.apache.directory.api.asn1.ber.tlv.BerValue;
28  import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder;
29  import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException;
30  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
31  import org.apache.directory.api.i18n.I18n;
32  import org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulActionConstants;
33  import org.apache.directory.api.util.Strings;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  
38  /**
39   * This class implements the Graceful shutdown. All the actions are declared in
40   * this class. As it is a singleton, these declaration are only done once. The
41   * grammar is :
42   * 
43   * <pre>
44   *  GracefulShutdwon ::= SEQUENCE {
45   *      timeOffline INTEGER (0..720) DEFAULT 0,
46   *      delay [0] INTEGER (0..86400) DEFAULT 0
47   *  }
48   * </pre>
49   * 
50   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
51   */
52  public final class GracefulShutdownRequestGrammar extends AbstractGrammar<GracefulShutdownRequestContainer>
53  {
54      /** The logger */
55      static final Logger LOG = LoggerFactory.getLogger( GracefulShutdownRequestGrammar.class );
56  
57      /** The instance of grammar. GracefulShutdownGrammar is a singleton */
58      private static GracefulShutdownRequestGrammar instance = new GracefulShutdownRequestGrammar();
59  
60  
61      /**
62       * Creates a new GracefulShutdownGrammar object.
63       */
64      @SuppressWarnings("unchecked")
65      private GracefulShutdownRequestGrammar()
66      {
67          setName( GracefulShutdownRequestGrammar.class.getName() );
68  
69          // Create the transitions table
70          super.transitions = new GrammarTransition[GracefulShutdownStatesEnum.LAST_GRACEFUL_SHUTDOWN_STATE.ordinal()][256];
71  
72          /**
73           * Transition from init state to graceful shutdown
74           * 
75           * GracefulShutdown ::= SEQUENCE {
76           *     ...
77           *     
78           * Creates the GracefulShutdown object
79           */
80          super.transitions[GracefulShutdownStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
81              new GrammarTransition<GracefulShutdownRequestContainer>( GracefulShutdownStatesEnum.START_STATE,
82                  GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE,
83                  UniversalTag.SEQUENCE.getValue(),
84                  new GrammarAction<GracefulShutdownRequestContainer>( "Init Graceful Shutdown" )
85                  {
86                      public void action( GracefulShutdownRequestContainer container ) throws DecoderException
87                      {
88                          // We may have nothing left
89                          if ( container.getCurrentTLV().getLength() == 0 )
90                          {
91                              container.setGrammarEndAllowed( true );
92                          }
93                      }
94                  } );
95  
96          /**
97           * Transition from graceful shutdown to time offline
98           *
99           * GracefulShutdown ::= SEQUENCE { 
100          *     timeOffline INTEGER (0..720) DEFAULT 0,
101          *     ...
102          *     
103          * Set the time offline value into the GracefulShutdown
104          * object.
105          */
106         super.transitions[GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE.ordinal()][UniversalTag.INTEGER
107             .getValue()] =
108             new GrammarTransition<GracefulShutdownRequestContainer>(
109                 GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE,
110                 GracefulShutdownStatesEnum.TIME_OFFLINE_STATE,
111                 UniversalTag.INTEGER.getValue(),
112                 new GrammarAction<GracefulShutdownRequestContainer>( "Set Graceful Shutdown time offline" )
113                 {
114                     public void action( GracefulShutdownRequestContainer container ) throws DecoderException
115                     {
116                         BerValue value = container.getCurrentTLV().getValue();
117 
118                         try
119                         {
120                             int timeOffline = IntegerDecoder.parse( value, 0, 720 );
121 
122                             if ( LOG.isDebugEnabled() )
123                             {
124                                 LOG.debug( I18n.msg( I18n.MSG_08216_TIME_OFFLINE, timeOffline ) );
125                             }
126 
127                             container.getGracefulShutdownRequest().setTimeOffline( timeOffline );
128                             container.setGrammarEndAllowed( true );
129                         }
130                         catch ( IntegerDecoderException ide )
131                         {
132                             String msg = I18n.err( I18n.ERR_08206_TIME_OFFLINE_DECODING_FAILED, Strings.dumpBytes( value.getData() ) );
133                             LOG.error( msg );
134                             throw new DecoderException( msg, ide );
135                         }
136                     }
137                 } );
138 
139         /**
140          * Transition from time offline to delay
141          * 
142          * GracefulShutdown ::= SEQUENCE { 
143          *     ... 
144          *     delay [0] INTEGER (0..86400) DEFAULT 0 }
145          * 
146          * Set the delay value into the GracefulShutdown
147          * object.
148          */
149         super.transitions[GracefulShutdownStatesEnum.TIME_OFFLINE_STATE.ordinal()][GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG] =
150             new GrammarTransition<GracefulShutdownRequestContainer>( GracefulShutdownStatesEnum.TIME_OFFLINE_STATE,
151                 GracefulShutdownStatesEnum.DELAY_STATE,
152                 GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG,
153 
154                 new GrammarAction<GracefulShutdownRequestContainer>( "Set Graceful Shutdown Delay" )
155                 {
156                     public void action( GracefulShutdownRequestContainer container ) throws DecoderException
157                     {
158                         BerValue value = container.getCurrentTLV().getValue();
159 
160                         try
161                         {
162                             int delay = IntegerDecoder.parse( value, 0, 86400 );
163 
164                             if ( LOG.isDebugEnabled() )
165                             {
166                                 LOG.debug( I18n.msg( I18n.MSG_08204_DELAY, delay ) );
167                             }
168 
169                             container.getGracefulShutdownRequest().setDelay( delay );
170                             container.setGrammarEndAllowed( true );
171                         }
172                         catch ( IntegerDecoderException ide )
173                         {
174                             String msg = I18n.err( I18n.ERR_08205_CANNOT_DECODE_DELAY, Strings.dumpBytes( value.getData() ) );
175                             LOG.error( msg );
176                             throw new DecoderException( msg, ide );
177                         }
178                     }
179                 } );
180 
181         /**
182          * Transition from graceful shutdown to delay
183          * 
184          * GracefulShutdown ::= SEQUENCE { 
185          *     ... 
186          *     delay [0] INTEGER (0..86400) DEFAULT 0 }
187          * 
188          * Set the delay value into the GracefulShutdown
189          * object.
190          */
191         super.transitions[GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE.ordinal()][GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG] =
192             new GrammarTransition<GracefulShutdownRequestContainer>(
193                 GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE,
194                 GracefulShutdownStatesEnum.DELAY_STATE,
195                 GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG,
196 
197                 new GrammarAction<GracefulShutdownRequestContainer>( "Set Graceful Shutdown Delay" )
198                 {
199                     public void action( GracefulShutdownRequestContainer container ) throws DecoderException
200                     {
201                         GracefulShutdownRequestContainer gracefulShutdownContainer = container;
202                         BerValue value = gracefulShutdownContainer.getCurrentTLV().getValue();
203 
204                         try
205                         {
206                             int delay = IntegerDecoder.parse( value, 0, 86400 );
207 
208                             if ( LOG.isDebugEnabled() )
209                             {
210                                 LOG.debug( I18n.msg( I18n.MSG_08204_DELAY, delay ) );
211                             }
212 
213                             gracefulShutdownContainer.getGracefulShutdownRequest().setDelay( delay );
214                             gracefulShutdownContainer.setGrammarEndAllowed( true );
215                         }
216                         catch ( IntegerDecoderException ide )
217                         {
218                             String msg = I18n.err( I18n.ERR_08205_CANNOT_DECODE_DELAY, Strings.dumpBytes( value.getData() ) );
219                             LOG.error( msg );
220                             throw new DecoderException( msg, ide );
221                         }
222                     }
223                 } );
224     }
225 
226 
227     /**
228      * This class is a singleton.
229      * 
230      * @return An instance on this grammar
231      */
232     public static GracefulShutdownRequestGrammar getInstance()
233     {
234         return instance;
235     }
236 }