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