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 * @see org.apache.camel.spi.ShutdownAware
039 */
040public interface ShutdownStrategy extends StaticService {
041
042    /**
043     * Shutdown the routes, forcing shutdown being more aggressive, if timeout occurred.
044     * <p/>
045     * This operation is used when {@link CamelContext} is shutting down, to ensure Camel will shutdown
046     * if messages seems to be <i>stuck</i>.
047     *
048     * @param context   the camel context
049     * @param routes    the routes, ordered by the order they was started
050     * @throws Exception is thrown if error shutting down the consumers, however its preferred to avoid this
051     */
052    void shutdownForced(CamelContext context, List<RouteStartupOrder> routes) throws Exception;
053
054    /**
055     * Shutdown the routes
056     *
057     * @param context   the camel context
058     * @param routes    the routes, ordered by the order they was started
059     * @throws Exception is thrown if error shutting down the consumers, however its preferred to avoid this
060     */
061    void shutdown(CamelContext context, List<RouteStartupOrder> routes) throws Exception;
062
063    /**
064     * Suspends the routes
065     *
066     * @param context   the camel context
067     * @param routes    the routes, ordered by the order they was started
068     * @throws Exception is thrown if error suspending the consumers, however its preferred to avoid this
069     */
070    void suspend(CamelContext context, List<RouteStartupOrder> routes) throws Exception;
071
072    /**
073     * Shutdown the routes using a specified timeout instead of the default timeout values
074     *
075     * @param context   the camel context
076     * @param routes    the routes, ordered by the order they was started
077     * @param timeout   timeout
078     * @param timeUnit  the unit to use
079     * @throws Exception is thrown if error shutting down the consumers, however its preferred to avoid this
080     */
081    void shutdown(CamelContext context, List<RouteStartupOrder> routes, long timeout, TimeUnit timeUnit) throws Exception;
082
083    /**
084     * Shutdown the route using a specified timeout instead of the default timeout values and supports abortAfterTimeout mode
085     *
086     * @param context   the camel context
087     * @param route     the route
088     * @param timeout   timeout
089     * @param timeUnit  the unit to use
090     * @param abortAfterTimeout   should abort shutdown after timeout
091     * @return <tt>true</tt> if the route is stopped before the timeout
092     * @throws Exception is thrown if error shutting down the consumer, however its preferred to avoid this
093     */
094    boolean shutdown(CamelContext context, RouteStartupOrder route, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout) throws Exception;
095
096    /**
097     * Suspends the routes using a specified timeout instead of the default timeout values
098     *
099     * @param context   the camel context
100     * @param routes    the routes, ordered by the order they was started
101     * @param timeout   timeout
102     * @param timeUnit  the unit to use
103     * @throws Exception is thrown if error suspending the consumers, however its preferred to avoid this
104     */
105    void suspend(CamelContext context, List<RouteStartupOrder> routes, long timeout, TimeUnit timeUnit) throws Exception;
106
107    /**
108     * Set an timeout to wait for the shutdown to complete.
109     * <p/>
110     * You must set a positive value. If you want to wait (forever) then use
111     * a very high value such as {@link Long#MAX_VALUE}
112     * <p/>
113     * The default timeout unit is <tt>SECONDS</tt>
114     *
115     * @throws IllegalArgumentException if the timeout value is 0 or negative
116     * @param timeout timeout
117     */
118    void setTimeout(long timeout);
119
120    /**
121     * Gets the timeout.
122     * <p/>
123     * The default timeout unit is <tt>SECONDS</tt>
124     *
125     * @return the timeout
126     */
127    long getTimeout();
128
129    /**
130     * Set the time unit to use
131     *
132     * @param timeUnit the unit to use
133     */
134    void setTimeUnit(TimeUnit timeUnit);
135
136    /**
137     * Gets the time unit used
138     *
139     * @return the time unit
140     */
141    TimeUnit getTimeUnit();
142
143    /**
144     * Whether Camel should try to suppress logging during shutdown and timeout was triggered,
145     * meaning forced shutdown is happening. And during forced shutdown we want to avoid logging
146     * errors/warnings et all in the logs as a side-effect of the forced timeout.
147     * <p/>
148     * By default this is <tt>false</tt>
149     * <p/>
150     * Notice the suppress is a <i>best effort</i> as there may still be some logs coming
151     * from 3rd party libraries and whatnot, which Camel cannot control.
152     *
153     * @param suppressLoggingOnTimeout <tt>true</tt> to suppress logging, false to log as usual.
154     */
155    void setSuppressLoggingOnTimeout(boolean suppressLoggingOnTimeout);
156
157    /**
158     * Whether Camel should try to suppress logging during shutdown and timeout was triggered,
159     * meaning forced shutdown is happening. And during forced shutdown we want to avoid logging
160     * errors/warnings et all in the logs as a side-effect of the forced timeout.
161     * <p/>
162     * By default this is <tt>false</tt>
163     * <p/>
164     * Notice the suppress is a <i>best effort</i> as there may still be some logs coming
165     * from 3rd party libraries and whatnot, which Camel cannot control.
166     */
167    boolean isSuppressLoggingOnTimeout();
168
169    /**
170     * Sets whether to force shutdown of all consumers when a timeout occurred and thus
171     * not all consumers was shutdown within that period.
172     * <p/>
173     * You should have good reasons to set this option to <tt>false</tt> as it means that the routes
174     * keep running and is halted abruptly when {@link CamelContext} has been shutdown.
175     *
176     * @param shutdownNowOnTimeout <tt>true</tt> to force shutdown, <tt>false</tt> to leave them running
177     */
178    void setShutdownNowOnTimeout(boolean shutdownNowOnTimeout);
179
180    /**
181     * Whether to force shutdown of all consumers when a timeout occurred.
182     *
183     * @return force shutdown or not
184     */
185    boolean isShutdownNowOnTimeout();
186
187    /**
188     * Sets whether routes should be shutdown in reverse or the same order as they where started.
189     *
190     * @param shutdownRoutesInReverseOrder <tt>true</tt> to shutdown in reverse order
191     */
192    void setShutdownRoutesInReverseOrder(boolean shutdownRoutesInReverseOrder);
193
194    /**
195     * Whether to shutdown routes in reverse order than they where started.
196     * <p/>
197     * This option is by default set to <tt>true</tt>.
198     *
199     * @return <tt>true</tt> if routes should be shutdown in reverse order.
200     */
201    boolean isShutdownRoutesInReverseOrder();
202
203    /**
204     * Sets whether to log information about the inflight {@link org.apache.camel.Exchange}s which are still running
205     * during a shutdown which didn't complete without the given timeout.
206     *
207     * @param logInflightExchangesOnTimeout <tt>true</tt> to log information about the inflight exchanges, <tt>false</tt> to not log
208     */
209    void setLogInflightExchangesOnTimeout(boolean logInflightExchangesOnTimeout);
210
211    /**
212     * Whether to log information about the inflight {@link org.apache.camel.Exchange}s which are still running
213     * during a shutdown which didn't complete without the given timeout.
214     */
215    boolean isLogInflightExchangesOnTimeout();
216
217    /**
218     * Whether a service is forced to shutdown.
219     * <p/>
220     * Can be used to signal to services that they are no longer allowed to run, such as if a forced
221     * shutdown is currently in progress.
222     * <p/>
223     * For example the Camel {@link org.apache.camel.processor.RedeliveryErrorHandler} uses this information
224     * to know if a forced shutdown is in progress, and then break out of redelivery attempts.
225     * 
226     * @param service the service
227     * @return <tt>true</tt> indicates the service is to be forced to shutdown, <tt>false</tt> the service can keep running.
228     */
229    boolean forceShutdown(Service service);
230
231    /**
232     * Whether a timeout has occurred during a shutdown.
233     */
234    boolean hasTimeoutOccurred();
235
236}