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 * <b>Important: </b> This is subject for change in a later Camel release, where we plan to only
084 * support getting the original IN message if you have enabled this option explicit.
085 *
086 * @return the original IN {@link Message}, may return <tt>null</tt> in a later Camel release (see important note).
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 }