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 org.apache.directory.api.asn1.DecoderException; 024import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; 025import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 026import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 027import org.apache.directory.api.asn1.ber.tlv.BerValue; 028import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder; 029import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException; 030import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 031import org.apache.directory.api.i18n.I18n; 032import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory; 033import org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulActionConstants; 034import org.apache.directory.api.ldap.extras.extended.gracefulShutdown.GracefulShutdownRequestImpl; 035import org.apache.directory.api.util.Strings; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039 040/** 041 * This class implements the Graceful shutdown. All the actions are declared in 042 * this class. As it is a singleton, these declaration are only done once. The 043 * grammar is : 044 * 045 * <pre> 046 * GracefulShutdwon ::= SEQUENCE { 047 * timeOffline INTEGER (0..720) DEFAULT 0, 048 * delay [0] INTEGER (0..86400) DEFAULT 0 049 * } 050 * </pre> 051 * 052 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 053 */ 054public final class GracefulShutdownGrammar extends AbstractGrammar<GracefulShutdownContainer> 055{ 056 /** The logger */ 057 static final Logger LOG = LoggerFactory.getLogger( GracefulShutdownGrammar.class ); 058 059 /** Speedup for logs */ 060 static final boolean IS_DEBUG = LOG.isDebugEnabled(); 061 062 /** The instance of grammar. GracefulShutdownGrammar is a singleton */ 063 private static GracefulShutdownGrammar instance = new GracefulShutdownGrammar(); 064 065 066 /** 067 * Creates a new GracefulShutdownGrammar object. 068 */ 069 @SuppressWarnings("unchecked") 070 private GracefulShutdownGrammar() 071 { 072 setName( GracefulShutdownGrammar.class.getName() ); 073 074 // Create the transitions table 075 super.transitions = new GrammarTransition[GracefulShutdownStatesEnum.LAST_GRACEFUL_SHUTDOWN_STATE.ordinal()][256]; 076 077 /** 078 * Transition from init state to graceful shutdown 079 * 080 * GracefulShutdown ::= SEQUENCE { 081 * ... 082 * 083 * Creates the GracefulShutdown object 084 */ 085 super.transitions[GracefulShutdownStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 086 new GrammarTransition<GracefulShutdownContainer>( GracefulShutdownStatesEnum.START_STATE, 087 GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE, 088 UniversalTag.SEQUENCE.getValue(), 089 new GrammarAction<GracefulShutdownContainer>( "Init GracefulShutdown" ) 090 { 091 public void action( GracefulShutdownContainer container ) 092 { 093 GracefulShutdownRequestDecorator gracefulShutdownRequest = new GracefulShutdownRequestDecorator( 094 LdapApiServiceFactory.getSingleton(), 095 new GracefulShutdownRequestImpl() ); 096 container.setGracefulShutdownRequest( gracefulShutdownRequest ); 097 container.setGrammarEndAllowed( true ); 098 } 099 } ); 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}