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.impl;
018
019import org.apache.camel.AsyncProcessor;
020import org.apache.camel.Consumer;
021import org.apache.camel.Endpoint;
022import org.apache.camel.EndpointAware;
023import org.apache.camel.Exchange;
024import org.apache.camel.Processor;
025import org.apache.camel.Route;
026import org.apache.camel.RouteAware;
027import org.apache.camel.spi.ExceptionHandler;
028import org.apache.camel.spi.UnitOfWork;
029import org.apache.camel.support.LoggingExceptionHandler;
030import org.apache.camel.support.ServiceSupport;
031import org.apache.camel.util.AsyncProcessorConverterHelper;
032import org.apache.camel.util.ServiceHelper;
033import org.apache.camel.util.URISupport;
034import org.apache.camel.util.UnitOfWorkHelper;
035import org.slf4j.Logger;
036import org.slf4j.LoggerFactory;
037
038/**
039 * A default consumer useful for implementation inheritance.
040 *
041 * @version 
042 */
043public class DefaultConsumer extends ServiceSupport implements Consumer, RouteAware {
044    protected final Logger log = LoggerFactory.getLogger(getClass());
045    private final Endpoint endpoint;
046    private final Processor processor;
047    private volatile AsyncProcessor asyncProcessor;
048    private ExceptionHandler exceptionHandler;
049    private Route route;
050
051    public DefaultConsumer(Endpoint endpoint, Processor processor) {
052        this.endpoint = endpoint;
053        this.processor = processor;
054        this.exceptionHandler = new LoggingExceptionHandler(endpoint.getCamelContext(), getClass());
055    }
056
057    @Override
058    public String toString() {
059        return "Consumer[" + URISupport.sanitizeUri(endpoint.getEndpointUri()) + "]";
060    }
061
062    public Route getRoute() {
063        return route;
064    }
065
066    public void setRoute(Route route) {
067        this.route = route;
068    }
069
070    /**
071     * If the consumer needs to defer done the {@link org.apache.camel.spi.UnitOfWork} on
072     * the processed {@link Exchange} then this method should be use to create and start
073     * the {@link UnitOfWork} on the exchange.
074     *
075     * @param exchange the exchange
076     * @return the created and started unit of work
077     * @throws Exception is thrown if error starting the unit of work
078     *
079     * @see #doneUoW(org.apache.camel.Exchange)
080     */
081    public UnitOfWork createUoW(Exchange exchange) throws Exception {
082        // if the exchange doesn't have from route id set, then set it if it originated
083        // from this unit of work
084        if (route != null && exchange.getFromRouteId() == null) {
085            exchange.setFromRouteId(route.getId());
086        }
087
088        UnitOfWork uow = endpoint.getCamelContext().getUnitOfWorkFactory().createUnitOfWork(exchange);
089        exchange.setUnitOfWork(uow);
090        uow.start();
091        return uow;
092    }
093
094    /**
095     * If the consumer needs to defer done the {@link org.apache.camel.spi.UnitOfWork} on
096     * the processed {@link Exchange} then this method should be executed when the consumer
097     * is finished processing the message.
098     *
099     * @param exchange the exchange
100     *
101     * @see #createUoW(org.apache.camel.Exchange)
102     */
103    public void doneUoW(Exchange exchange) {
104        UnitOfWorkHelper.doneUow(exchange.getUnitOfWork(), exchange);
105    }
106
107    public Endpoint getEndpoint() {
108        return endpoint;
109    }
110
111    public Processor getProcessor() {
112        return processor;
113    }
114
115    /**
116     * Provides an {@link org.apache.camel.AsyncProcessor} interface to the configured
117     * processor on the consumer. If the processor does not implement the interface,
118     * it will be adapted so that it does.
119     */
120    public synchronized AsyncProcessor getAsyncProcessor() {
121        if (asyncProcessor == null) {            
122            asyncProcessor = AsyncProcessorConverterHelper.convert(processor);
123        }
124        return asyncProcessor;
125    }
126
127    public ExceptionHandler getExceptionHandler() {
128        return exceptionHandler;
129    }
130
131    public void setExceptionHandler(ExceptionHandler exceptionHandler) {
132        this.exceptionHandler = exceptionHandler;
133    }
134
135    protected void doStop() throws Exception {
136        log.debug("Stopping consumer: {}", this);
137        ServiceHelper.stopServices(processor);
138    }
139
140    protected void doStart() throws Exception {
141        log.debug("Starting consumer: {}", this);
142        ServiceHelper.startServices(processor);
143    }
144
145    /**
146     * Handles the given exception using the {@link #getExceptionHandler()}
147     * 
148     * @param t the exception to handle
149     */
150    protected void handleException(Throwable t) {
151        Throwable newt = (t == null) ? new IllegalArgumentException("Handling [null] exception") : t;
152        getExceptionHandler().handleException(newt);
153    }
154
155    /**
156     * Handles the given exception using the {@link #getExceptionHandler()}
157     *
158     * @param message additional message about the exception
159     * @param t the exception to handle
160     */
161    protected void handleException(String message, Throwable t) {
162        Throwable newt = (t == null) ? new IllegalArgumentException("Handling [null] exception") : t;
163        getExceptionHandler().handleException(message, newt);
164    }
165}