001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.spi;
018    
019    import java.util.List;
020    import java.util.concurrent.TimeUnit;
021    
022    import org.apache.camel.CamelContext;
023    import org.apache.camel.Service;
024    import org.apache.camel.StaticService;
025    
026    /**
027     * Pluggable shutdown strategy executed during shutdown of routes.
028     * <p/>
029     * Shutting down routes in a reliable and graceful manner is not a trivial task. Therefore Camel provides a pluggable
030     * strategy allowing 3rd party to use their own strategy if needed.
031     * <p/>
032     * The key problem is to stop the input consumers for the routes such that no new messages is coming into Camel.
033     * But at the same time still keep the routes running so the existing in flight exchanges can still be run to
034     * completion. On top of that there are some in memory components (such as SEDA) which may have pending messages
035     * on its in memory queue which we want to run to completion as well, otherwise they will get lost.
036     * <p/>
037     * Camel provides a default strategy which supports all that that can be used as inspiration for your own strategy.
038     *
039     * @version 
040     * @see org.apache.camel.spi.ShutdownAware
041     */
042    public interface ShutdownStrategy extends StaticService {
043    
044        /**
045         * Shutdown the routes, forcing shutdown being more aggressive, if timeout occurred.
046         * <p/>
047         * This operation is used when {@link CamelContext} is shutting down, to ensure Camel will shutdown
048         * if messages seems to be <i>stuck</i>.
049         *
050         * @param context   the camel context
051         * @param routes    the routes, ordered by the order they was started
052         * @throws Exception is thrown if error shutting down the consumers, however its preferred to avoid this
053         */
054        void shutdownForced(CamelContext context, List<RouteStartupOrder> routes) throws Exception;
055    
056        /**
057         * Shutdown the routes
058         *
059         * @param context   the camel context
060         * @param routes    the routes, ordered by the order they was started
061         * @throws Exception is thrown if error shutting down the consumers, however its preferred to avoid this
062         */
063        void shutdown(CamelContext context, List<RouteStartupOrder> routes) throws Exception;
064    
065        /**
066         * Suspends the routes
067         *
068         * @param context   the camel context
069         * @param routes    the routes, ordered by the order they was started
070         * @throws Exception is thrown if error suspending the consumers, however its preferred to avoid this
071         */
072        void suspend(CamelContext context, List<RouteStartupOrder> routes) throws Exception;
073    
074        /**
075         * Shutdown the routes using a specified timeout instead of the default timeout values
076         *
077         * @param context   the camel context
078         * @param routes    the routes, ordered by the order they was started
079         * @param timeout   timeout
080         * @param timeUnit  the unit to use
081         * @throws Exception is thrown if error shutting down the consumers, however its preferred to avoid this
082         */
083        void shutdown(CamelContext context, List<RouteStartupOrder> routes, long timeout, TimeUnit timeUnit) throws Exception;
084    
085        /**
086         * Shutdown the route using a specified timeout instead of the default timeout values and supports abortAfterTimeout mode
087         *
088         * @param context   the camel context
089         * @param route     the route
090         * @param timeout   timeout
091         * @param timeUnit  the unit to use
092         * @param abortAfterTimeout   should abort shutdown after timeout
093         * @return <tt>true</tt> if the route is stopped before the timeout
094         * @throws Exception is thrown if error shutting down the consumer, however its preferred to avoid this
095         */
096        boolean shutdown(CamelContext context, RouteStartupOrder route, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout) throws Exception;
097    
098        /**
099         * Suspends the routes using a specified timeout instead of the default timeout values
100         *
101         * @param context   the camel context
102         * @param routes    the routes, ordered by the order they was started
103         * @param timeout   timeout
104         * @param timeUnit  the unit to use
105         * @throws Exception is thrown if error suspending the consumers, however its preferred to avoid this
106         */
107        void suspend(CamelContext context, List<RouteStartupOrder> routes, long timeout, TimeUnit timeUnit) throws Exception;
108    
109        /**
110         * Set an timeout to wait for the shutdown to complete.
111         * <p/>
112         * You must set a positive value. If you want to wait (forever) then use
113         * a very high value such as {@link Long#MAX_VALUE}
114         * <p/>
115         * The default timeout unit is <tt>SECONDS</tt>
116         *
117         * @throws IllegalArgumentException if the timeout value is 0 or negative
118         * @param timeout timeout
119         */
120        void setTimeout(long timeout);
121    
122        /**
123         * Gets the timeout.
124         * <p/>
125         * The default timeout unit is <tt>SECONDS</tt>
126         *
127         * @return the timeout
128         */
129        long getTimeout();
130    
131        /**
132         * Set the time unit to use
133         *
134         * @param timeUnit the unit to use
135         */
136        void setTimeUnit(TimeUnit timeUnit);
137    
138        /**
139         * Gets the time unit used
140         *
141         * @return the time unit
142         */
143        TimeUnit getTimeUnit();
144    
145        /**
146         * Whether Camel should try to suppress logging during shutdown and timeout was triggered,
147         * meaning forced shutdown is happening. And during forced shutdown we want to avoid logging
148         * errors/warnings et all in the logs as a side-effect of the forced timeout.
149         * <p/>
150         * By default this is <tt>false</tt>
151         * <p/>
152         * Notice the suppress is a <i>best effort</i> as there may still be some logs coming
153         * from 3rd party libraries and whatnot, which Camel cannot control.
154         *
155         * @param suppressLoggingOnTimeout <tt>true</tt> to suppress logging, false to log as usual.
156         */
157        void setSuppressLoggingOnTimeout(boolean suppressLoggingOnTimeout);
158    
159        /**
160         * Whether Camel should try to suppress logging during shutdown and timeout was triggered,
161         * meaning forced shutdown is happening. And during forced shutdown we want to avoid logging
162         * errors/warnings et all in the logs as a side-effect of the forced timeout.
163         * <p/>
164         * By default this is <tt>false</tt>
165         * <p/>
166         * Notice the suppress is a <i>best effort</i> as there may still be some logs coming
167         * from 3rd party libraries and whatnot, which Camel cannot control.
168         */
169        boolean isSuppressLoggingOnTimeout();
170    
171        /**
172         * Sets whether to force shutdown of all consumers when a timeout occurred and thus
173         * not all consumers was shutdown within that period.
174         * <p/>
175         * You should have good reasons to set this option to <tt>false</tt> as it means that the routes
176         * keep running and is halted abruptly when {@link CamelContext} has been shutdown.
177         *
178         * @param shutdownNowOnTimeout <tt>true</tt> to force shutdown, <tt>false</tt> to leave them running
179         */
180        void setShutdownNowOnTimeout(boolean shutdownNowOnTimeout);
181    
182        /**
183         * Whether to force shutdown of all consumers when a timeout occurred.
184         *
185         * @return force shutdown or not
186         */
187        boolean isShutdownNowOnTimeout();
188    
189        /**
190         * Sets whether routes should be shutdown in reverse or the same order as they where started.
191         *
192         * @param shutdownRoutesInReverseOrder <tt>true</tt> to shutdown in reverse order
193         */
194        void setShutdownRoutesInReverseOrder(boolean shutdownRoutesInReverseOrder);
195    
196        /**
197         * Whether to shutdown routes in reverse order than they where started.
198         * <p/>
199         * This option is by default set to <tt>true</tt>.
200         *
201         * @return <tt>true</tt> if routes should be shutdown in reverse order.
202         */
203        boolean isShutdownRoutesInReverseOrder();
204    
205        /**
206         * Whether a service is forced to shutdown.
207         * <p/>
208         * Can be used to signal to services that they are no longer allowed to run, such as if a forced
209         * shutdown is currently in progress.
210         * <p/>
211         * For example the Camel {@link org.apache.camel.processor.RedeliveryErrorHandler} uses this information
212         * to know if a forced shutdown is in progress, and then break out of redelivery attempts.
213         * 
214         * @param service the service
215         * @return <tt>true</tt> indicates the service is to be forced to shutdown, <tt>false</tt> the service can keep running.
216         */
217        boolean forceShutdown(Service service);
218    
219        /**
220         * Whether a timeout has occurred during a shutdown.
221         */
222        boolean hasTimeoutOccurred();
223    
224    }