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;
018
019 import java.util.List;
020 import java.util.Map;
021
022 import org.apache.camel.spi.Synchronization;
023 import org.apache.camel.spi.UnitOfWork;
024
025 /**
026 * An Exchange is the message container holding the information during the entire routing of
027 * a {@link Message} received by a {@link Consumer}.
028 * <p/>
029 * During processing down the {@link Processor} chain, the {@link Exchange} provides access to the
030 * current (not the original) request and response {@link Message} messages. The {@link Exchange}
031 * also holds meta-data during its entire lifetime stored as properties accessible using the
032 * various {@link #getProperty(String)} methods. The {@link #setProperty(String, Object)} is
033 * used to store a property. For example you can use this to store security, SLA related
034 * data or any other information deemed useful throughout processing. If an {@link Exchange}
035 * failed during routing the {@link Exception} that caused the failure is stored and accessible
036 * via the {@link #getException()} method.
037 * <p/>
038 * An Exchange is created when a {@link Consumer} receives a request. A new {@link Message} is
039 * created, the request is set as the body of the {@link Message} and depending on the {@link Consumer}
040 * other {@link Endpoint} and protocol related information is added as headers on the {@link Message}.
041 * Then an Exchange is created and the newly created {@link Message} is set as the in on the Exchange.
042 * Therefore an Exchange starts its life in a {@link Consumer}. The Exchange is then sent down the
043 * {@link Route} for processing along a {@link Processor} chain. The {@link Processor} as the name
044 * suggests is what processes the {@link Message} in the Exchange and Camel, in addition to
045 * providing out-of-the-box a large number of useful processors, it also allows you to create your own.
046 * The rule Camel uses is to take the out {@link Message} produced by the previous {@link Processor}
047 * and set it as the in for the next {@link Processor}. If the previous {@link Processor} did not
048 * produce an out, then the in of the previous {@link Processor} is sent as the next in. At the
049 * end of the processing chain, depending on the {@link ExchangePattern Message Exchange Pattern} (or MEP)
050 * the last out (or in of no out available) is sent by the {@link Consumer} back to the original caller.
051 * <p/>
052 * Camel, in addition to providing out-of-the-box a large number of useful processors, it also allows
053 * you to implement and use your own. When the Exchange is passed to a {@link Processor}, it always
054 * contains an in {@link Message} and no out {@link Message}. The {@link Processor} <b>may</b> produce
055 * an out, depending on the nature of the {@link Processor}. The in {@link Message} can be accessed
056 * using the {@link #getIn()} method. Since the out message is null when entering the {@link Processor},
057 * the {@link #getOut()} method is actually a convenient factory method that will lazily instantiate a
058 * {@link org.apache.camel.impl.DefaultMessage} which you could populate. As an alternative you could
059 * also instantiate your specialized {@link Message} and set it on the exchange using the
060 * {@link #setOut(org.apache.camel.Message)} method. Please note that a {@link Message} contains not only
061 * the body but also headers and attachments. If you are creating a new {@link Message} the headers and
062 * attachments of the in {@link Message} are not automatically copied to the out by Camel and you'll have
063 * to set the headers and attachments you need yourself. If your {@link Processor} is not producing a
064 * different {@link Message} but only needs to slightly modify the in, you can simply update the in
065 * {@link Message} returned by {@link #getIn()}.
066 * <p/>
067 * See this <a href="http://camel.apache.org/using-getin-or-getout-methods-on-exchange.html">FAQ entry</a>
068 * for more details.
069 *
070 */
071 public interface Exchange {
072
073 String AUTHENTICATION = "CamelAuthentication";
074 String AUTHENTICATION_FAILURE_POLICY_ID = "CamelAuthenticationFailurePolicyId";
075 String ACCEPT_CONTENT_TYPE = "CamelAcceptContentType";
076 String AGGREGATED_SIZE = "CamelAggregatedSize";
077 String AGGREGATED_TIMEOUT = "CamelAggregatedTimeout";
078 String AGGREGATED_COMPLETED_BY = "CamelAggregatedCompletedBy";
079 String AGGREGATED_CORRELATION_KEY = "CamelAggregatedCorrelationKey";
080 String AGGREGATION_STRATEGY = "CamelAggregationStrategy";
081 String AGGREGATION_COMPLETE_ALL_GROUPS = "CamelAggregationCompleteAllGroups";
082 String AGGREGATION_COMPLETE_ALL_GROUPS_INCLUSIVE = "CamelAggregationCompleteAllGroupsInclusive";
083 String ASYNC_WAIT = "CamelAsyncWait";
084
085 String BATCH_INDEX = "CamelBatchIndex";
086 String BATCH_SIZE = "CamelBatchSize";
087 String BATCH_COMPLETE = "CamelBatchComplete";
088 String BEAN_METHOD_NAME = "CamelBeanMethodName";
089 String BEAN_MULTI_PARAMETER_ARRAY = "CamelBeanMultiParameterArray";
090 String BINDING = "CamelBinding";
091 // do not prefix with Camel and use lower-case starting letter as its a shared key
092 // used across other Apache products such as AMQ, SMX etc.
093 String BREADCRUMB_ID = "breadcrumbId";
094
095 String CHARSET_NAME = "CamelCharsetName";
096 String CREATED_TIMESTAMP = "CamelCreatedTimestamp";
097 String CONTENT_ENCODING = "Content-Encoding";
098 String CONTENT_LENGTH = "Content-Length";
099 String CONTENT_TYPE = "Content-Type";
100 String CORRELATION_ID = "CamelCorrelationId";
101
102 String DATASET_INDEX = "CamelDataSetIndex";
103 String DEFAULT_CHARSET_PROPERTY = "org.apache.camel.default.charset";
104 String DESTINATION_OVERRIDE_URL = "CamelDestinationOverrideUrl";
105 String DISABLE_HTTP_STREAM_CACHE = "CamelDisableHttpStreamCache";
106 String DUPLICATE_MESSAGE = "CamelDuplicateMessage";
107
108 String EXCEPTION_CAUGHT = "CamelExceptionCaught";
109 String EXCEPTION_HANDLED = "CamelExceptionHandled";
110 String EVALUATE_EXPRESSION_RESULT = "CamelEvaluateExpressionResult";
111 String ERRORHANDLER_HANDLED = "CamelErrorHandlerHandled";
112 String EXTERNAL_REDELIVERED = "CamelExternalRedelivered";
113
114 String FAILURE_HANDLED = "CamelFailureHandled";
115 String FAILURE_ENDPOINT = "CamelFailureEndpoint";
116 String FAILURE_ROUTE_ID = "CamelFailureRouteId";
117 String FILTER_NON_XML_CHARS = "CamelFilterNonXmlChars";
118 String FILE_LOCAL_WORK_PATH = "CamelFileLocalWorkPath";
119 String FILE_NAME = "CamelFileName";
120 String FILE_NAME_ONLY = "CamelFileNameOnly";
121 String FILE_NAME_PRODUCED = "CamelFileNameProduced";
122 String FILE_NAME_CONSUMED = "CamelFileNameConsumed";
123 String FILE_PATH = "CamelFilePath";
124 String FILE_PARENT = "CamelFileParent";
125 String FILE_LAST_MODIFIED = "CamelFileLastModified";
126 String FILE_LENGTH = "CamelFileLength";
127 String FILTER_MATCHED = "CamelFilterMatched";
128 String FILE_LOCK_FILE_ACQUIRED = "CamelFileLockFileAcquired";
129 String FILE_LOCK_FILE_NAME = "CamelFileLockFileName";
130
131 String GROUPED_EXCHANGE = "CamelGroupedExchange";
132
133 String HTTP_BASE_URI = "CamelHttpBaseUri";
134 String HTTP_CHARACTER_ENCODING = "CamelHttpCharacterEncoding";
135 String HTTP_METHOD = "CamelHttpMethod";
136 String HTTP_PATH = "CamelHttpPath";
137 String HTTP_PROTOCOL_VERSION = "CamelHttpProtocolVersion";
138 String HTTP_QUERY = "CamelHttpQuery";
139 String HTTP_RAW_QUERY = "CamelHttpRawQuery";
140 String HTTP_RESPONSE_CODE = "CamelHttpResponseCode";
141 String HTTP_URI = "CamelHttpUri";
142 String HTTP_URL = "CamelHttpUrl";
143 String HTTP_CHUNKED = "CamelHttpChunked";
144 String HTTP_SERVLET_REQUEST = "CamelHttpServletRequest";
145 String HTTP_SERVLET_RESPONSE = "CamelHttpServletResponse";
146
147 String INTERCEPTED_ENDPOINT = "CamelInterceptedEndpoint";
148 String INTERCEPT_SEND_TO_ENDPOINT_WHEN_MATCHED = "CamelInterceptSendToEndpointWhenMatched";
149
150 String LANGUAGE_SCRIPT = "CamelLanguageScript";
151 String LOG_DEBUG_BODY_MAX_CHARS = "CamelLogDebugBodyMaxChars";
152 String LOG_DEBUG_BODY_STREAMS = "CamelLogDebugStreams";
153 String LOOP_INDEX = "CamelLoopIndex";
154 String LOOP_SIZE = "CamelLoopSize";
155
156 String MAXIMUM_CACHE_POOL_SIZE = "CamelMaximumCachePoolSize";
157 String MAXIMUM_ENDPOINT_CACHE_SIZE = "CamelMaximumEndpointCacheSize";
158 String MESSAGE_HISTORY = "CamelMessageHistory";
159 String MULTICAST_INDEX = "CamelMulticastIndex";
160 String MULTICAST_COMPLETE = "CamelMulticastComplete";
161
162 String NOTIFY_EVENT = "CamelNotifyEvent";
163
164 String ON_COMPLETION = "CamelOnCompletion";
165 String OVERRULE_FILE_NAME = "CamelOverruleFileName";
166
167 String PARENT_UNIT_OF_WORK = "CamelParentUnitOfWork";
168
169 String RECIPIENT_LIST_ENDPOINT = "CamelRecipientListEndpoint";
170 String RECEIVED_TIMESTAMP = "CamelReceivedTimestamp";
171 String REDELIVERED = "CamelRedelivered";
172 String REDELIVERY_COUNTER = "CamelRedeliveryCounter";
173 String REDELIVERY_MAX_COUNTER = "CamelRedeliveryMaxCounter";
174 String REDELIVERY_EXHAUSTED = "CamelRedeliveryExhausted";
175 String REDELIVERY_DELAY = "CamelRedeliveryDelay";
176 String ROLLBACK_ONLY = "CamelRollbackOnly";
177 String ROLLBACK_ONLY_LAST = "CamelRollbackOnlyLast";
178 String ROUTE_STOP = "CamelRouteStop";
179
180 String SOAP_ACTION = "CamelSoapAction";
181 String SKIP_GZIP_ENCODING = "CamelSkipGzipEncoding";
182 String SLIP_ENDPOINT = "CamelSlipEndpoint";
183 String SPLIT_INDEX = "CamelSplitIndex";
184 String SPLIT_COMPLETE = "CamelSplitComplete";
185 String SPLIT_SIZE = "CamelSplitSize";
186
187 String TIMER_COUNTER = "CamelTimerCounter";
188 String TIMER_FIRED_TIME = "CamelTimerFiredTime";
189 String TIMER_NAME = "CamelTimerName";
190 String TIMER_PERIOD = "CamelTimerPeriod";
191 String TIMER_TIME = "CamelTimerTime";
192 String TO_ENDPOINT = "CamelToEndpoint";
193 String TRACE_EVENT = "CamelTraceEvent";
194 String TRACE_EVENT_NODE_ID = "CamelTraceEventNodeId";
195 String TRACE_EVENT_TIMESTAMP = "CamelTraceEventTimestamp";
196 String TRACE_EVENT_EXCHANGE = "CamelTraceEventExchange";
197 String TRY_ROUTE_BLOCK = "TryRouteBlock";
198 String TRANSFER_ENCODING = "Transfer-Encoding";
199
200 String UNIT_OF_WORK_EXHAUSTED = "CamelUnitOfWorkExhausted";
201 /**
202 * @deprecated UNIT_OF_WORK_PROCESS_SYNC is not in use and will be removed in future Camel release
203 */
204 @Deprecated
205 String UNIT_OF_WORK_PROCESS_SYNC = "CamelUnitOfWorkProcessSync";
206
207 String XSLT_FILE_NAME = "CamelXsltFileName";
208
209 /**
210 * Returns the {@link ExchangePattern} (MEP) of this exchange.
211 *
212 * @return the message exchange pattern of this exchange
213 */
214 ExchangePattern getPattern();
215
216 /**
217 * Allows the {@link ExchangePattern} (MEP) of this exchange to be customized.
218 *
219 * This typically won't be required as an exchange can be created with a specific MEP
220 * by calling {@link Endpoint#createExchange(ExchangePattern)} but it is here just in case
221 * it is needed.
222 *
223 * @param pattern the pattern
224 */
225 void setPattern(ExchangePattern pattern);
226
227 /**
228 * Returns a property associated with this exchange by name
229 *
230 * @param name the name of the property
231 * @return the value of the given property or <tt>null</tt> if there is no property for
232 * the given name
233 */
234 Object getProperty(String name);
235
236 /**
237 * Returns a property associated with this exchange by name
238 *
239 * @param name the name of the property
240 * @param defaultValue the default value to return if property was absent
241 * @return the value of the given property or <tt>defaultValue</tt> if there is no
242 * property for the given name
243 */
244 Object getProperty(String name, Object defaultValue);
245
246 /**
247 * Returns a property associated with this exchange by name and specifying
248 * the type required
249 *
250 * @param name the name of the property
251 * @param type the type of the property
252 * @return the value of the given property or <tt>null</tt> if there is no property for
253 * the given name or <tt>null</tt> if it cannot be converted to the given type
254 */
255 <T> T getProperty(String name, Class<T> type);
256
257 /**
258 * Returns a property associated with this exchange by name and specifying
259 * the type required
260 *
261 * @param name the name of the property
262 * @param defaultValue the default value to return if property was absent
263 * @param type the type of the property
264 * @return the value of the given property or <tt>defaultValue</tt> if there is no property for
265 * the given name or <tt>null</tt> if it cannot be converted to the given type
266 */
267 <T> T getProperty(String name, Object defaultValue, Class<T> type);
268
269 /**
270 * Sets a property on the exchange
271 *
272 * @param name of the property
273 * @param value to associate with the name
274 */
275 void setProperty(String name, Object value);
276
277 /**
278 * Removes the given property on the exchange
279 *
280 * @param name of the property
281 * @return the old value of the property
282 */
283 Object removeProperty(String name);
284
285 /**
286 * Returns all of the properties associated with the exchange
287 *
288 * @return all the headers in a Map
289 */
290 Map<String, Object> getProperties();
291
292 /**
293 * Returns whether any properties has been set
294 *
295 * @return <tt>true</tt> if any properties has been set
296 */
297 boolean hasProperties();
298
299 /**
300 * Returns the inbound request message
301 *
302 * @return the message
303 */
304 Message getIn();
305
306 /**
307 * Returns the inbound request message as the given type
308 *
309 * @param type the given type
310 * @return the message as the given type or <tt>null</tt> if not possible to covert to given type
311 */
312 <T> T getIn(Class<T> type);
313
314 /**
315 * Sets the inbound message instance
316 *
317 * @param in the inbound message
318 */
319 void setIn(Message in);
320
321 /**
322 * Returns the outbound message, lazily creating one if one has not already
323 * been associated with this exchange.
324 * <p/>
325 * <br/><b>Important:</b> If you want to change the current message, then use {@link #getIn()} instead as it will
326 * ensure headers etc. is kept and propagated when routing continues. Bottom line end users should rarely use
327 * this method.
328 * <p/>
329 * <br/>If you want to test whether an OUT message have been set or not, use the {@link #hasOut()} method.
330 * <p/>
331 * See also the class java doc for this {@link Exchange} for more details and this
332 * <a href="http://camel.apache.org/using-getin-or-getout-methods-on-exchange.html">FAQ entry</a>.
333 *
334 * @return the response
335 * @see #getIn()
336 */
337 Message getOut();
338
339 /**
340 * Returns the outbound request message as the given type
341 * <p/>
342 * <br/><b>Important:</b> If you want to change the current message, then use {@link #getIn()} instead as it will
343 * ensure headers etc. is kept and propagated when routing continues. Bottom line end users should rarely use
344 * this method.
345 * <p/>
346 * <br/>If you want to test whether an OUT message have been set or not, use the {@link #hasOut()} method.
347 * <p/>
348 * See also the class java doc for this {@link Exchange} for more details and this
349 * <a href="http://camel.apache.org/using-getin-or-getout-methods-on-exchange.html">FAQ entry</a>.
350 *
351 * @param type the given type
352 * @return the message as the given type or <tt>null</tt> if not possible to covert to given type
353 * @see #getIn(Class)
354 */
355 <T> T getOut(Class<T> type);
356
357 /**
358 * Returns whether an OUT message has been set or not.
359 *
360 * @return <tt>true</tt> if an OUT message exists, <tt>false</tt> otherwise.
361 */
362 boolean hasOut();
363
364 /**
365 * Sets the outbound message
366 *
367 * @param out the outbound message
368 */
369 void setOut(Message out);
370
371 /**
372 * Returns the exception associated with this exchange
373 *
374 * @return the exception (or null if no faults)
375 */
376 Exception getException();
377
378 /**
379 * Returns the exception associated with this exchange.
380 * <p/>
381 * Is used to get the caused exception that typically have been wrapped in some sort
382 * of Camel wrapper exception
383 * <p/>
384 * The strategy is to look in the exception hierarchy to find the first given cause that matches the type.
385 * Will start from the bottom (the real cause) and walk upwards.
386 *
387 * @param type the exception type
388 * @return the exception (or <tt>null</tt> if no caused exception matched)
389 */
390 <T> T getException(Class<T> type);
391
392 /**
393 * Sets the exception associated with this exchange
394 * <p/>
395 * Camel will wrap {@link Throwable} into {@link Exception} type to
396 * accommodate for the {@link #getException()} method returning a plain {@link Exception} type.
397 *
398 * @param t the caused exception
399 */
400 void setException(Throwable t);
401
402 /**
403 * Returns true if this exchange failed due to either an exception or fault
404 *
405 * @return true if this exchange failed due to either an exception or fault
406 * @see Exchange#getException()
407 * @see Message#setFault(boolean)
408 * @see Message#isFault()
409 */
410 boolean isFailed();
411
412 /**
413 * Returns true if this exchange is transacted
414 */
415 boolean isTransacted();
416
417 /**
418 * Returns true if this exchange is an external initiated redelivered message (such as a JMS broker).
419 * <p/>
420 * <b>Important: </b> It is not always possible to determine if the message is a redelivery
421 * or not, and therefore <tt>null</tt> is returned. Such an example would be a JDBC message.
422 * However JMS brokers provides details if a message is redelivered.
423 *
424 * @return <tt>true</tt> if redelivered, <tt>false</tt> if not, <tt>null</tt> if not able to determine
425 */
426 Boolean isExternalRedelivered();
427
428 /**
429 * Returns true if this exchange is marked for rollback
430 */
431 boolean isRollbackOnly();
432
433 /**
434 * Returns the container so that a processor can resolve endpoints from URIs
435 *
436 * @return the container which owns this exchange
437 */
438 CamelContext getContext();
439
440 /**
441 * Creates a copy of the current message exchange so that it can be
442 * forwarded to another destination
443 */
444 Exchange copy();
445
446 /**
447 * Returns the endpoint which originated this message exchange if a consumer on an endpoint
448 * created the message exchange, otherwise this property will be <tt>null</tt>
449 */
450 Endpoint getFromEndpoint();
451
452 /**
453 * Sets the endpoint which originated this message exchange. This method
454 * should typically only be called by {@link org.apache.camel.Endpoint} implementations
455 *
456 * @param fromEndpoint the endpoint which is originating this message exchange
457 */
458 void setFromEndpoint(Endpoint fromEndpoint);
459
460 /**
461 * Returns the route id which originated this message exchange if a route consumer on an endpoint
462 * created the message exchange, otherwise this property will be <tt>null</tt>
463 */
464 String getFromRouteId();
465
466 /**
467 * Sets the route id which originated this message exchange. This method
468 * should typically only be called by the internal framework.
469 *
470 * @param fromRouteId the from route id
471 */
472 void setFromRouteId(String fromRouteId);
473
474 /**
475 * Returns the unit of work that this exchange belongs to; which may map to
476 * zero, one or more physical transactions
477 */
478 UnitOfWork getUnitOfWork();
479
480 /**
481 * Sets the unit of work that this exchange belongs to; which may map to
482 * zero, one or more physical transactions
483 */
484 void setUnitOfWork(UnitOfWork unitOfWork);
485
486 /**
487 * Returns the exchange id (unique)
488 */
489 String getExchangeId();
490
491 /**
492 * Set the exchange id
493 */
494 void setExchangeId(String id);
495
496 /**
497 * Adds a {@link org.apache.camel.spi.Synchronization} to be invoked as callback when
498 * this exchange is completed.
499 *
500 * @param onCompletion the callback to invoke on completion of this exchange
501 */
502 void addOnCompletion(Synchronization onCompletion);
503
504 /**
505 * Checks if the passed {@link org.apache.camel.spi.Synchronization} instance is
506 * already contained on this exchange.
507 *
508 * @param onCompletion the callback instance that is being checked for
509 * @return <tt>true</tt>, if callback instance is already contained on this exchange, else <tt>false</tt>
510 */
511 boolean containsOnCompletion(Synchronization onCompletion);
512
513 /**
514 * Handover all the on completions from this exchange to the target exchange.
515 *
516 * @param target the target exchange
517 */
518 void handoverCompletions(Exchange target);
519
520 /**
521 * Handover all the on completions from this exchange
522 *
523 * @return the on completions
524 */
525 List<Synchronization> handoverCompletions();
526
527 }