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