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.spi; 018 019import java.util.function.Predicate; 020 021import org.apache.camel.AsyncCallback; 022import org.apache.camel.Exchange; 023import org.apache.camel.Message; 024import org.apache.camel.Processor; 025import org.apache.camel.Route; 026import org.apache.camel.Service; 027 028/** 029 * An object representing the unit of work processing an {@link Exchange} 030 * which allows the use of {@link Synchronization} hooks. This object might map one-to-one with 031 * a transaction in JPA or Spring; or might not. 032 */ 033public interface UnitOfWork extends Service { 034 035 /** 036 * Adds a synchronization hook 037 * 038 * @param synchronization the hook 039 */ 040 void addSynchronization(Synchronization synchronization); 041 042 /** 043 * Removes a synchronization hook 044 * 045 * @param synchronization the hook 046 */ 047 void removeSynchronization(Synchronization synchronization); 048 049 /** 050 * Checks if the passed synchronization hook is already part of this unit of work. 051 * 052 * @param synchronization the hook 053 * @return <tt>true</tt>, if the passed synchronization is part of this unit of work, else <tt>false</tt> 054 */ 055 boolean containsSynchronization(Synchronization synchronization); 056 057 /** 058 * Handover all the registered synchronizations to the target {@link org.apache.camel.Exchange}. 059 * <p/> 060 * This is used when a route turns into asynchronous and the {@link org.apache.camel.Exchange} that 061 * is continued and routed in the async thread should do the on completion callbacks instead of the 062 * original synchronous thread. 063 * 064 * @param target the target exchange 065 */ 066 void handoverSynchronization(Exchange target); 067 068 /** 069 * Handover all the registered synchronizations to the target {@link org.apache.camel.Exchange}. 070 * <p/> 071 * This is used when a route turns into asynchronous and the {@link org.apache.camel.Exchange} that 072 * is continued and routed in the async thread should do the on completion callbacks instead of the 073 * original synchronous thread. 074 * 075 * @param target the target exchange 076 * @param filter optional filter to only handover if filter returns <tt>true</tt> 077 */ 078 void handoverSynchronization(Exchange target, Predicate<Synchronization> filter); 079 080 /** 081 * Invoked when this unit of work has been completed, whether it has failed or completed 082 * 083 * @param exchange the current exchange 084 */ 085 void done(Exchange exchange); 086 087 /** 088 * Invoked when this unit of work is about to be routed by the given route. 089 * 090 * @param exchange the current exchange 091 * @param route the route 092 */ 093 void beforeRoute(Exchange exchange, Route route); 094 095 /** 096 * Invoked when this unit of work is done being routed by the given route. 097 * 098 * @param exchange the current exchange 099 * @param route the route 100 */ 101 void afterRoute(Exchange exchange, Route route); 102 103 /** 104 * Returns the unique ID of this unit of work, lazily creating one if it does not yet have one 105 * 106 * @return the unique ID 107 */ 108 String getId(); 109 110 /** 111 * Gets the original IN {@link Message} this Unit of Work was started with. 112 * <p/> 113 * The original message is only returned if the option {@link org.apache.camel.RuntimeConfiguration#isAllowUseOriginalMessage()} 114 * is enabled. If its disabled an <tt>IllegalStateException</tt> is thrown. 115 * 116 * @return the original IN {@link Message}, or <tt>null</tt> if using original message is disabled. 117 */ 118 Message getOriginalInMessage(); 119 120 /** 121 * Gets tracing information 122 * 123 * @return trace information 124 */ 125 @Deprecated 126 TracedRouteNodes getTracedRouteNodes(); 127 128 /** 129 * Are we transacted? 130 * 131 * @return <tt>true</tt> if transacted, <tt>false</tt> otherwise 132 */ 133 boolean isTransacted(); 134 135 /** 136 * Are we already transacted by the given transaction key? 137 * 138 * @param key the transaction key 139 * @return <tt>true</tt> if already, <tt>false</tt> otherwise 140 */ 141 boolean isTransactedBy(Object key); 142 143 /** 144 * Mark this UnitOfWork as being transacted by the given transaction key. 145 * <p/> 146 * When the transaction is completed then invoke the {@link #endTransactedBy(Object)} method using the same key. 147 * 148 * @param key the transaction key 149 */ 150 void beginTransactedBy(Object key); 151 152 /** 153 * Mark this UnitOfWork as not transacted anymore by the given transaction definition. 154 * 155 * @param key the transaction key 156 */ 157 void endTransactedBy(Object key); 158 159 /** 160 * Gets the {@link RouteContext} that this {@link UnitOfWork} currently is being routed through. 161 * <p/> 162 * Notice that an {@link Exchange} can be routed through multiple routes and thus the 163 * {@link org.apache.camel.spi.RouteContext} can change over time. 164 * 165 * @return the route context 166 * @see #pushRouteContext(RouteContext) 167 * @see #popRouteContext() 168 */ 169 RouteContext getRouteContext(); 170 171 /** 172 * Pushes the {@link RouteContext} that this {@link UnitOfWork} currently is being routed through. 173 * <p/> 174 * Notice that an {@link Exchange} can be routed through multiple routes and thus the 175 * {@link org.apache.camel.spi.RouteContext} can change over time. 176 * 177 * @param routeContext the route context 178 */ 179 void pushRouteContext(RouteContext routeContext); 180 181 /** 182 * When finished being routed under the current {@link org.apache.camel.spi.RouteContext} 183 * it should be removed. 184 * 185 * @return the route context or <tt>null</tt> if none existed 186 */ 187 RouteContext popRouteContext(); 188 189 /** 190 * Strategy for optional work to be execute before processing 191 * <p/> 192 * For example the {@link org.apache.camel.impl.MDCUnitOfWork} leverages this 193 * to ensure MDC is handled correctly during routing exchanges using the 194 * asynchronous routing engine. 195 * 196 * @param processor the processor to be executed 197 * @param exchange the current exchange 198 * @param callback the callback 199 * @return the callback to be used (can return a wrapped callback) 200 */ 201 AsyncCallback beforeProcess(Processor processor, Exchange exchange, AsyncCallback callback); 202 203 /** 204 * Strategy for optional work to be executed after the processing 205 * 206 * @param processor the processor executed 207 * @param exchange the current exchange 208 * @param callback the callback used 209 * @param doneSync whether the process was done synchronously or asynchronously 210 */ 211 void afterProcess(Processor processor, Exchange exchange, AsyncCallback callback, boolean doneSync); 212 213 /** 214 * Create a child unit of work, which is associated to this unit of work as its parent. 215 * <p/> 216 * This is often used when EIPs need to support {@link SubUnitOfWork}s. For example a splitter, 217 * where the sub messages of the splitter all participate in the same sub unit of work. 218 * That sub unit of work then decides whether the Splitter (in general) is failed or a 219 * processed successfully. 220 * 221 * @param childExchange the child exchange 222 * @return the created child unit of work 223 * @see SubUnitOfWork 224 * @see SubUnitOfWorkCallback 225 */ 226 UnitOfWork createChildUnitOfWork(Exchange childExchange); 227 228 /** 229 * Sets the parent unit of work. 230 * 231 * @param parentUnitOfWork the parent 232 */ 233 void setParentUnitOfWork(UnitOfWork parentUnitOfWork); 234 235 /** 236 * Gets the {@link SubUnitOfWorkCallback} if this unit of work participates in a sub unit of work. 237 * 238 * @return the callback, or <tt>null</tt> if this unit of work is not part of a sub unit of work. 239 * @see #beginSubUnitOfWork(org.apache.camel.Exchange) 240 */ 241 SubUnitOfWorkCallback getSubUnitOfWorkCallback(); 242 243 /** 244 * Begins a {@link SubUnitOfWork}, where sub (child) unit of works participate in a parent unit of work. 245 * The {@link SubUnitOfWork} will callback to the parent unit of work using {@link SubUnitOfWorkCallback}s. 246 * 247 * @param exchange the exchange 248 */ 249 void beginSubUnitOfWork(Exchange exchange); 250 251 /** 252 * Ends a {@link SubUnitOfWork}. 253 * <p/> 254 * The {@link #beginSubUnitOfWork(org.apache.camel.Exchange)} must have been invoked 255 * prior to this operation. 256 * 257 * @param exchange the exchange 258 */ 259 void endSubUnitOfWork(Exchange exchange); 260 261}