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}