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.support;
018
019import java.util.concurrent.TimeUnit;
020
021import org.apache.camel.Consumer;
022import org.apache.camel.Exchange;
023import org.apache.camel.Route;
024import org.apache.camel.spi.ExceptionHandler;
025import org.apache.camel.spi.RoutePolicy;
026import org.apache.camel.util.ServiceHelper;
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030/**
031 * A base class for developing custom {@link RoutePolicy} implementations.
032 *
033 * @version 
034 */
035public abstract class RoutePolicySupport extends ServiceSupport implements RoutePolicy {
036
037    protected final Logger log = LoggerFactory.getLogger(getClass());
038    private ExceptionHandler exceptionHandler;
039
040    public void onInit(Route route) {
041        if (exceptionHandler == null) {
042            exceptionHandler = new LoggingExceptionHandler(route.getRouteContext().getCamelContext(), getClass());
043        }
044    }
045
046    public void onRemove(Route route) {
047        // noop
048    }
049
050    @Override
051    public void onStart(Route route) {
052        // noop
053    }
054
055    @Override
056    public void onStop(Route route) {
057        // noop
058    }
059
060    @Override
061    public void onSuspend(Route route) {
062        // noop
063    }
064
065    @Override
066    public void onResume(Route route) {
067        // noop
068    }
069
070    public void onExchangeBegin(Route route, Exchange exchange) {
071        // noop
072    }
073
074    public void onExchangeDone(Route route, Exchange exchange) {
075        // noop
076    }
077
078    public boolean startConsumer(Consumer consumer) throws Exception {
079        boolean resumed = ServiceHelper.resumeService(consumer);
080        if (resumed) {
081            log.debug("Resuming consumer {}", consumer);
082        }
083        return resumed;
084    }
085
086    public boolean stopConsumer(Consumer consumer) throws Exception {
087        boolean suspended = ServiceHelper.suspendService(consumer);
088        if (suspended) {
089            log.debug("Suspended consumer {}", consumer);
090        }
091        return suspended;
092    }
093
094    public void startRoute(Route route) throws Exception {
095        route.getRouteContext().getCamelContext().startRoute(route.getId());
096    }
097
098    public void resumeRoute(Route route) throws Exception {
099        route.getRouteContext().getCamelContext().resumeRoute(route.getId());
100    }
101
102    public void suspendRoute(Route route) throws Exception {
103        route.getRouteContext().getCamelContext().suspendRoute(route.getId());
104    }
105
106    public void suspendRoute(Route route, long timeout, TimeUnit timeUnit) throws Exception {
107        route.getRouteContext().getCamelContext().suspendRoute(route.getId(), timeout, timeUnit);
108    }
109
110    /**
111     * @see #stopRouteAsync(Route)
112     */
113    public void stopRoute(Route route) throws Exception {
114        route.getRouteContext().getCamelContext().stopRoute(route.getId());
115    }
116
117    /**
118     * @see #stopRouteAsync(Route)
119     */
120    public void stopRoute(Route route, long timeout, TimeUnit timeUnit) throws Exception {
121        route.getRouteContext().getCamelContext().stopRoute(route.getId(), timeout, timeUnit);
122    }
123
124    /**
125     * Allows to stop a route asynchronously using a separate background thread which can allow any current in-flight exchange
126     * to complete while the route is being shutdown.
127     * You may attempt to stop a route from processing an exchange which would be in-flight and therefore attempting to stop
128     * the route will defer due there is an inflight exchange in-progress. By stopping the route independently using a separate
129     * thread ensures the exchange can continue process and complete and the route can be stopped.
130     */
131    public void stopRouteAsync(final Route route) {
132        String threadId = route.getRouteContext().getCamelContext().getExecutorServiceManager().resolveThreadName("StopRouteAsync");
133        Runnable task = () -> {
134            try {
135                route.getRouteContext().getCamelContext().stopRoute(route.getId());
136            } catch (Exception e) {
137                handleException(e);
138            }
139        };
140        new Thread(task, threadId).start();
141    }
142
143    /**
144     * Handles the given exception using the {@link #getExceptionHandler()}
145     *
146     * @param t the exception to handle
147     */
148    protected void handleException(Throwable t) {
149        if (exceptionHandler != null) {
150            exceptionHandler.handleException(t);
151        }
152    }
153
154    @Override
155    protected void doStart() throws Exception {
156        // noop
157    }
158
159    @Override
160    protected void doStop() throws Exception {
161        // noop
162    }
163
164    public ExceptionHandler getExceptionHandler() {
165        return exceptionHandler;
166    }
167
168    public void setExceptionHandler(ExceptionHandler exceptionHandler) {
169        this.exceptionHandler = exceptionHandler;
170    }
171
172}