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     */
020    package org.apache.directory.shared.ldap.message.extended;
021    
022    
023    import javax.naming.NamingException;
024    import javax.naming.ldap.ExtendedResponse;
025    
026    import org.apache.directory.shared.asn1.codec.DecoderException;
027    import org.apache.directory.shared.asn1.codec.EncoderException;
028    import org.apache.directory.shared.i18n.I18n;
029    import org.apache.directory.shared.ldap.codec.extended.operations.gracefulShutdown.GracefulShutdown;
030    import org.apache.directory.shared.ldap.codec.extended.operations.gracefulShutdown.GracefulShutdownDecoder;
031    import org.apache.directory.shared.ldap.message.ExtendedRequestImpl;
032    import org.apache.directory.shared.ldap.message.internal.InternalResultResponse;
033    import org.slf4j.Logger;
034    import org.slf4j.LoggerFactory;
035    
036    
037    /**
038     * An extended operation requesting the server to shutdown it's LDAP service
039     * port while allowing established clients to complete or abandon operations
040     * already in progress. More information about this extended request is
041     * available here: <a href="ahttp://docs.safehaus.org:8080/x/GR">LDAP Extensions
042     * for Graceful Shutdown</a>.
043     * 
044     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
045     * @version $Rev: 912436 $
046     */
047    public class GracefulShutdownRequest extends ExtendedRequestImpl
048    {
049        private static final Logger log = LoggerFactory.getLogger( GracefulShutdownRequest.class );
050    
051        private static final long serialVersionUID = -4682291068700593492L;
052    
053        public static final String EXTENSION_OID = "1.3.6.1.4.1.18060.0.1.3";
054    
055        /** Undetermined value used for timeOffline */
056        public static final int UNDETERMINED = 0;
057    
058        /** The shutdown is immediate */
059        public static final int NOW = 0;
060    
061        /** offline Time after disconnection */
062        private int timeOffline;
063    
064        /** Delay before disconnection */
065        private int delay;
066    
067    
068        public GracefulShutdownRequest(int messageId)
069        {
070            this( messageId, UNDETERMINED, NOW );
071        }
072    
073    
074        public GracefulShutdownRequest(int messageId, int timeOffline, int delay)
075        {
076            super( messageId );
077            setOid( EXTENSION_OID );
078            this.timeOffline = timeOffline;
079            this.delay = delay;
080        }
081    
082    
083        private void encodePayload() throws EncoderException
084        {
085            GracefulShutdown gs = new GracefulShutdown();
086            gs.setDelay( this.delay );
087            gs.setTimeOffline( this.timeOffline );
088            payload = gs.encode().array();
089        }
090    
091    
092        public void setPayload( byte[] payload )
093        {
094            GracefulShutdownDecoder decoder = new GracefulShutdownDecoder();
095            try
096            {
097                GracefulShutdown gs = ( GracefulShutdown ) decoder.decode( payload );
098                if ( payload != null )
099                {
100                    this.payload = new byte[ payload.length ];
101                    System.arraycopy( payload, 0, this.payload, 0, payload.length );
102                } else {
103                    this.payload = null;
104                }
105                this.timeOffline = gs.getTimeOffline();
106                this.delay = gs.getDelay();
107            }
108            catch ( DecoderException e )
109            {
110                log.error( I18n.err( I18n.ERR_04165 ), e );
111                throw new RuntimeException( e );
112            }
113        }
114    
115    
116        public ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset, int length )
117            throws NamingException
118        {
119            return ( ExtendedResponse ) getResultResponse();
120        }
121    
122    
123        public byte[] getEncodedValue()
124        {
125            return getPayload();
126        }
127    
128    
129        public byte[] getPayload()
130        {
131            if ( payload == null )
132            {
133                try
134                {
135                    encodePayload();
136                }
137                catch ( EncoderException e )
138                {
139                    log.error( I18n.err( I18n.ERR_04164 ), e );
140                    throw new RuntimeException( e );
141                }
142            }
143    
144            return super.getPayload();
145        }
146    
147    
148        public InternalResultResponse getResultResponse()
149        {
150            if ( response == null )
151            {
152                GracefulShutdownResponse gsr = new GracefulShutdownResponse( getMessageId() );
153                response = gsr;
154            }
155    
156            return response;
157        }
158    
159    
160        // -----------------------------------------------------------------------
161        // Parameters of the Extended Request Payload
162        // -----------------------------------------------------------------------
163    
164        public int getDelay()
165        {
166            return delay;
167        }
168    
169    
170        public void setDelay( int delay )
171        {
172            this.delay = delay;
173        }
174    
175    
176        public int getTimeOffline()
177        {
178            return timeOffline;
179        }
180    
181    
182        public void setTimeOffline( int timeOffline )
183        {
184            this.timeOffline = timeOffline;
185        }
186    }