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.processor; 018 019import org.apache.camel.Exchange; 020import org.apache.camel.Message; 021import org.slf4j.Logger; 022 023import static org.apache.camel.util.ExchangeHelper.hasExceptionBeenHandledByErrorHandler; 024 025/** 026 * Helper for processing {@link org.apache.camel.Exchange} in a 027 * <a href="http://camel.apache.org/pipes-and-filters.html">pipeline</a>. 028 * 029 * @version 030 */ 031public final class PipelineHelper { 032 033 private PipelineHelper() { 034 } 035 036 /** 037 * Should we continue processing the exchange? 038 * 039 * @param exchange the next exchange 040 * @param message a message to use when logging that we should not continue processing 041 * @param log a logger 042 * @return <tt>true</tt> to continue processing, <tt>false</tt> to break out, for example if an exception occurred. 043 */ 044 public static boolean continueProcessing(Exchange exchange, String message, Logger log) { 045 // check for error if so we should break out 046 boolean exceptionHandled = hasExceptionBeenHandledByErrorHandler(exchange); 047 if (exchange.isFailed() || exchange.isRollbackOnly() || exceptionHandled) { 048 // We need to write a warning message when the exception and fault message be set at the same time 049 Message msg = exchange.hasOut() ? exchange.getOut() : exchange.getIn(); 050 if (msg.isFault() && exchange.getException() != null) { 051 StringBuilder sb = new StringBuilder(); 052 sb.append("Message exchange has failed: " + message + " for exchange: ").append(exchange); 053 sb.append(" Warning: Both fault and exception exists on the exchange, its best practice to only set one of them."); 054 sb.append(" Exception: ").append(exchange.getException()); 055 sb.append(" Fault: ").append(msg); 056 if (exceptionHandled) { 057 sb.append(" Handled by the error handler."); 058 } 059 log.warn(sb.toString()); 060 } 061 // The Exchange.ERRORHANDLED_HANDLED property is only set if satisfactory handling was done 062 // by the error handler. It's still an exception, the exchange still failed. 063 if (log.isDebugEnabled()) { 064 StringBuilder sb = new StringBuilder(); 065 sb.append("Message exchange has failed: " + message + " for exchange: ").append(exchange); 066 if (exchange.isRollbackOnly()) { 067 sb.append(" Marked as rollback only."); 068 } 069 if (exchange.getException() != null) { 070 sb.append(" Exception: ").append(exchange.getException()); 071 } 072 if (msg.isFault()) { 073 sb.append(" Fault: ").append(msg); 074 } 075 if (exceptionHandled) { 076 sb.append(" Handled by the error handler."); 077 } 078 log.debug(sb.toString()); 079 } 080 081 return false; 082 } 083 084 // check for stop 085 Object stop = exchange.getProperty(Exchange.ROUTE_STOP); 086 if (stop != null) { 087 boolean doStop = exchange.getContext().getTypeConverter().convertTo(Boolean.class, exchange, stop); 088 if (doStop) { 089 log.debug("ExchangeId: {} is marked to stop routing: {}", exchange.getExchangeId(), exchange); 090 return false; 091 } 092 } 093 094 return true; 095 } 096 097 /** 098 * Strategy method to create the next exchange from the previous exchange. 099 * <p/> 100 * Remember to copy the original exchange id otherwise correlation of ids in the log is a problem 101 * 102 * @param previousExchange the previous exchange 103 * @return a new exchange 104 */ 105 public static Exchange createNextExchange(Exchange previousExchange) { 106 Exchange answer = previousExchange; 107 108 // now lets set the input of the next exchange to the output of the 109 // previous message if it is not null 110 if (answer.hasOut()) { 111 answer.setIn(answer.getOut()); 112 answer.setOut(null); 113 } 114 return answer; 115 } 116 117}