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