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.reifier; 018 019import java.util.concurrent.ExecutorService; 020 021import org.apache.camel.Predicate; 022import org.apache.camel.Processor; 023import org.apache.camel.model.OnCompletionDefinition; 024import org.apache.camel.model.OnCompletionMode; 025import org.apache.camel.model.ProcessorDefinition; 026import org.apache.camel.model.ProcessorDefinitionHelper; 027import org.apache.camel.processor.CamelInternalProcessor; 028import org.apache.camel.processor.OnCompletionProcessor; 029import org.apache.camel.spi.RouteContext; 030 031public class OnCompletionReifier extends ProcessorReifier<OnCompletionDefinition> { 032 033 public OnCompletionReifier(ProcessorDefinition<?> definition) { 034 super((OnCompletionDefinition)definition); 035 } 036 037 @Override 038 public Processor createProcessor(RouteContext routeContext) throws Exception { 039 // assign whether this was a route scoped onCompletion or not 040 // we need to know this later when setting the parent, as only route 041 // scoped should have parent 042 // Note: this logic can possible be removed when the Camel routing 043 // engine decides at runtime 044 // to apply onCompletion in a more dynamic fashion than current code 045 // base 046 // and therefore is in a better position to decide among context/route 047 // scoped OnCompletion at runtime 048 Boolean routeScoped = definition.getRouteScoped(); 049 if (routeScoped == null) { 050 routeScoped = definition.getParent() != null; 051 } 052 053 boolean isOnCompleteOnly = definition.getOnCompleteOnly() != null && definition.getOnCompleteOnly(); 054 boolean isOnFailureOnly = definition.getOnFailureOnly() != null && definition.getOnFailureOnly(); 055 boolean isParallelProcessing = definition.getParallelProcessing() != null && definition.getParallelProcessing(); 056 boolean original = definition.getUseOriginalMessagePolicy() != null && definition.getUseOriginalMessagePolicy(); 057 058 if (isOnCompleteOnly && isOnFailureOnly) { 059 throw new IllegalArgumentException("Both onCompleteOnly and onFailureOnly cannot be true. Only one of them can be true. On node: " + this); 060 } 061 if (original) { 062 // ensure allow original is turned on 063 routeContext.setAllowUseOriginalMessage(true); 064 } 065 066 Processor childProcessor = this.createChildProcessor(routeContext, true); 067 068 // wrap the on completion route in a unit of work processor 069 CamelInternalProcessor internal = new CamelInternalProcessor(childProcessor); 070 internal.addAdvice(new CamelInternalProcessor.UnitOfWorkProcessorAdvice(routeContext)); 071 072 routeContext.setOnCompletion(getId(definition, routeContext), internal); 073 074 Predicate when = null; 075 if (definition.getOnWhen() != null) { 076 when = definition.getOnWhen().getExpression().createPredicate(routeContext); 077 } 078 079 boolean shutdownThreadPool = ProcessorDefinitionHelper.willCreateNewThreadPool(routeContext, definition, isParallelProcessing); 080 ExecutorService threadPool = ProcessorDefinitionHelper.getConfiguredExecutorService(routeContext, "OnCompletion", definition, isParallelProcessing); 081 082 // should be after consumer by default 083 boolean afterConsumer = definition.getMode() == null || definition.getMode() == OnCompletionMode.AfterConsumer; 084 085 OnCompletionProcessor answer = new OnCompletionProcessor(routeContext.getCamelContext(), internal, threadPool, shutdownThreadPool, isOnCompleteOnly, isOnFailureOnly, when, 086 original, afterConsumer); 087 return answer; 088 } 089 090}