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 */
017package org.apache.camel.spi;
018
019import java.util.List;
020import java.util.concurrent.TimeUnit;
021
022import org.apache.camel.CamelContext;
023import org.apache.camel.Service;
024import 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 */
042public 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}