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, then <tt>null</tt> is returned. 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 TracedRouteNodes getTracedRouteNodes(); 126 127 /** 128 * Are we transacted? 129 * 130 * @return <tt>true</tt> if transacted, <tt>false</tt> otherwise 131 */ 132 boolean isTransacted(); 133 134 /** 135 * Are we already transacted by the given transaction key? 136 * 137 * @param key the transaction key 138 * @return <tt>true</tt> if already, <tt>false</tt> otherwise 139 */ 140 boolean isTransactedBy(Object key); 141 142 /** 143 * Mark this UnitOfWork as being transacted by the given transaction key. 144 * <p/> 145 * When the transaction is completed then invoke the {@link #endTransactedBy(Object)} method using the same key. 146 * 147 * @param key the transaction key 148 */ 149 void beginTransactedBy(Object key); 150 151 /** 152 * Mark this UnitOfWork as not transacted anymore by the given transaction definition. 153 * 154 * @param key the transaction key 155 */ 156 void endTransactedBy(Object key); 157 158 /** 159 * Gets the {@link RouteContext} that this {@link UnitOfWork} currently is being routed through. 160 * <p/> 161 * Notice that an {@link Exchange} can be routed through multiple routes and thus the 162 * {@link org.apache.camel.spi.RouteContext} can change over time. 163 * 164 * @return the route context 165 * @see #pushRouteContext(RouteContext) 166 * @see #popRouteContext() 167 */ 168 RouteContext getRouteContext(); 169 170 /** 171 * Pushes the {@link RouteContext} that this {@link UnitOfWork} currently is being routed through. 172 * <p/> 173 * Notice that an {@link Exchange} can be routed through multiple routes and thus the 174 * {@link org.apache.camel.spi.RouteContext} can change over time. 175 * 176 * @param routeContext the route context 177 */ 178 void pushRouteContext(RouteContext routeContext); 179 180 /** 181 * When finished being routed under the current {@link org.apache.camel.spi.RouteContext} 182 * it should be removed. 183 * 184 * @return the route context or <tt>null</tt> if none existed 185 */ 186 RouteContext popRouteContext(); 187 188 /** 189 * Strategy for optional work to be execute before processing 190 * <p/> 191 * For example the {@link org.apache.camel.impl.MDCUnitOfWork} leverages this 192 * to ensure MDC is handled correctly during routing exchanges using the 193 * asynchronous routing engine. 194 * 195 * @param processor the processor to be executed 196 * @param exchange the current exchange 197 * @param callback the callback 198 * @return the callback to be used (can return a wrapped callback) 199 */ 200 AsyncCallback beforeProcess(Processor processor, Exchange exchange, AsyncCallback callback); 201 202 /** 203 * Strategy for optional work to be executed after the processing 204 * 205 * @param processor the processor executed 206 * @param exchange the current exchange 207 * @param callback the callback used 208 * @param doneSync whether the process was done synchronously or asynchronously 209 */ 210 void afterProcess(Processor processor, Exchange exchange, AsyncCallback callback, boolean doneSync); 211 212 /** 213 * Create a child unit of work, which is associated to this unit of work as its parent. 214 * <p/> 215 * This is often used when EIPs need to support {@link SubUnitOfWork}s. For example a splitter, 216 * where the sub messages of the splitter all participate in the same sub unit of work. 217 * That sub unit of work then decides whether the Splitter (in general) is failed or a 218 * processed successfully. 219 * 220 * @param childExchange the child exchange 221 * @return the created child unit of work 222 * @see SubUnitOfWork 223 * @see SubUnitOfWorkCallback 224 */ 225 UnitOfWork createChildUnitOfWork(Exchange childExchange); 226 227 /** 228 * Sets the parent unit of work. 229 * 230 * @param parentUnitOfWork the parent 231 */ 232 void setParentUnitOfWork(UnitOfWork parentUnitOfWork); 233 234 /** 235 * Gets the {@link SubUnitOfWorkCallback} if this unit of work participates in a sub unit of work. 236 * 237 * @return the callback, or <tt>null</tt> if this unit of work is not part of a sub unit of work. 238 * @see #beginSubUnitOfWork(org.apache.camel.Exchange) 239 */ 240 SubUnitOfWorkCallback getSubUnitOfWorkCallback(); 241 242 /** 243 * Begins a {@link SubUnitOfWork}, where sub (child) unit of works participate in a parent unit of work. 244 * The {@link SubUnitOfWork} will callback to the parent unit of work using {@link SubUnitOfWorkCallback}s. 245 * 246 * @param exchange the exchange 247 */ 248 void beginSubUnitOfWork(Exchange exchange); 249 250 /** 251 * Ends a {@link SubUnitOfWork}. 252 * <p/> 253 * The {@link #beginSubUnitOfWork(org.apache.camel.Exchange)} must have been invoked 254 * prior to this operation. 255 * 256 * @param exchange the exchange 257 */ 258 void endSubUnitOfWork(Exchange exchange); 259 260}