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; 018 019import java.util.concurrent.Future; 020import java.util.function.Supplier; 021 022/** 023 * Template for working with Camel and sending {@link Message} instances in an 024 * {@link Exchange} to an {@link Endpoint} using a <i>fluent</i> build style. 025 * <br/> 026 * <p/><b>Important:</b> Read the javadoc of each method carefully to ensure the behavior of the method is understood. 027 * Some methods is for <tt>InOnly</tt>, others for <tt>InOut</tt> MEP. And some methods throws 028 * {@link org.apache.camel.CamelExecutionException} while others stores any thrown exception on the returned 029 * {@link Exchange}. 030 * <br/> 031 * <p/>The {@link FluentProducerTemplate} is <b>thread safe</b>. 032 * <br/> 033 * <p/>All the methods which sends a message may throw {@link FailedToCreateProducerException} in 034 * case the {@link Producer} could not be created. Or a {@link NoSuchEndpointException} if the endpoint could 035 * not be resolved. There may be other related exceptions being thrown which occurs <i>before</i> the {@link Producer} 036 * has started sending the message. 037 * <br/> 038 * <p/>All the send or request methods will return the content according to this strategy: 039 * <ul> 040 * <li>throws {@link org.apache.camel.CamelExecutionException} if processing failed <i>during</i> routing 041 * with the caused exception wrapped</li> 042 * <li>The <tt>fault.body</tt> if there is a fault message set and its not <tt>null</tt></li> 043 * <li>Either <tt>IN</tt> or <tt>OUT</tt> body according to the message exchange pattern. If the pattern is 044 * Out capable then the <tt>OUT</tt> body is returned, otherwise <tt>IN</tt>. 045 * </ul> 046 * <br/> 047 * <p/>Before using the template it must be started. 048 * And when you are done using the template, make sure to {@link #stop()} the template. 049 * <br/> 050 * <p/><b>Important note on usage:</b> See this 051 * <a href="http://camel.apache.org/why-does-camel-use-too-many-threads-with-producertemplate.html">FAQ entry</a> 052 * before using. 053 * 054 * @see ProducerTemplate 055 * @see ConsumerTemplate 056 */ 057public interface FluentProducerTemplate extends Service { 058 059 /** 060 * Get the {@link CamelContext} 061 * 062 * @return camelContext the Camel context 063 */ 064 CamelContext getCamelContext(); 065 066 // Configuration methods 067 // ----------------------------------------------------------------------- 068 069 /** 070 * Gets the maximum cache size used in the backing cache pools. 071 * 072 * @return the maximum cache size 073 */ 074 int getMaximumCacheSize(); 075 076 /** 077 * Sets a custom maximum cache size to use in the backing cache pools. 078 * 079 * @param maximumCacheSize the custom maximum cache size 080 */ 081 void setMaximumCacheSize(int maximumCacheSize); 082 083 /** 084 * Gets an approximated size of the current cached resources in the backing cache pools. 085 * 086 * @return the size of current cached resources 087 */ 088 int getCurrentCacheSize(); 089 090 /** 091 * Get the default endpoint to use if none is specified 092 * 093 * @return the default endpoint instance 094 */ 095 Endpoint getDefaultEndpoint(); 096 097 /** 098 * Sets the default endpoint to use if none is specified 099 * 100 * @param defaultEndpoint the default endpoint instance 101 */ 102 void setDefaultEndpoint(Endpoint defaultEndpoint); 103 104 /** 105 * Sets the default endpoint uri to use if none is specified 106 * 107 * @param endpointUri the default endpoint uri 108 */ 109 void setDefaultEndpointUri(String endpointUri); 110 111 /** 112 * Sets whether the {@link org.apache.camel.spi.EventNotifier} should be 113 * used by this {@link ProducerTemplate} to send events about the {@link Exchange} 114 * being sent. 115 * <p/> 116 * By default this is enabled. 117 * 118 * @param enabled <tt>true</tt> to enable, <tt>false</tt> to disable. 119 */ 120 void setEventNotifierEnabled(boolean enabled); 121 122 /** 123 * Whether the {@link org.apache.camel.spi.EventNotifier} should be 124 * used by this {@link ProducerTemplate} to send events about the {@link Exchange} 125 * being sent. 126 * 127 * @return <tt>true</tt> if enabled, <tt>false</tt> otherwise 128 */ 129 boolean isEventNotifierEnabled(); 130 131 /** 132 * Cleanup the cache (purging stale entries) 133 */ 134 void cleanUp(); 135 136 // Fluent methods 137 // ----------------------------------------------------------------------- 138 139 /** 140 * Remove the body and headers. 141 */ 142 FluentProducerTemplate clearAll(); 143 144 /** 145 * Set the header 146 * 147 * @param key the key of the header 148 * @param value the value of the header 149 */ 150 FluentProducerTemplate withHeader(String key, Object value); 151 152 /** 153 * Remove the headers. 154 */ 155 FluentProducerTemplate clearHeaders(); 156 157 /** 158 * Set the message body 159 * 160 * @param body the body 161 */ 162 FluentProducerTemplate withBody(Object body); 163 164 /** 165 * Set the message body after converting it to the given type 166 * 167 * @param body the body 168 * @param type the type which the body should be converted to 169 */ 170 FluentProducerTemplate withBodyAs(Object body, Class<?> type); 171 172 /** 173 * Remove the body. 174 */ 175 FluentProducerTemplate clearBody(); 176 177 /** 178 * To customize the producer template for advanced usage like to set the 179 * executor service to use. 180 * 181 * <pre> 182 * {@code 183 * FluentProducerTemplate.on(context) 184 * .withTemplateCustomizer( 185 * template -> { 186 * template.setExecutorService(myExecutor); 187 * template.setMaximumCacheSize(10); 188 * } 189 * ) 190 * .withBody("the body") 191 * .to("direct:start") 192 * .request()} 193 * </pre> 194 * 195 * Note that it is invoked only once. 196 * 197 * @param templateCustomizer the customizer 198 */ 199 FluentProducerTemplate withTemplateCustomizer(java.util.function.Consumer<ProducerTemplate> templateCustomizer); 200 201 /** 202 * Set the exchange to use for send. 203 * 204 * When using withExchange then you must use the send method (request is not supported). 205 * 206 * @param exchange the exchange 207 */ 208 FluentProducerTemplate withExchange(Exchange exchange); 209 210 /** 211 * Set the exchangeSupplier which will be invoke to get the exchange to be 212 * used for send. 213 * 214 * When using withExchange then you must use the send method (request is not supported). 215 * 216 * @param exchangeSupplier the supplier 217 */ 218 FluentProducerTemplate withExchange(Supplier<Exchange> exchangeSupplier); 219 220 /** 221 * Set the processor to use for send/request. 222 * 223 * <pre> 224 * {@code 225 * FluentProducerTemplate.on(context) 226 * .withProcessor( 227 * exchange -> { 228 * exchange.getIn().setHeader("Key1", "Val1"); 229 * exchange.getIn().setHeader("Key2", "Val2"); 230 * exchange.getIn().setBody("the body"); 231 * } 232 * ) 233 * .to("direct:start") 234 * .request()} 235 * </pre> 236 * 237 * @param processor 238 */ 239 FluentProducerTemplate withProcessor(Processor processor); 240 241 /** 242 * Set the processorSupplier which will be invoke to get the processor to be 243 * used for send/request. 244 * 245 * @param processorSupplier the supplier 246 */ 247 FluentProducerTemplate withProcessor(Supplier<Processor> processorSupplier); 248 249 /** 250 * Endpoint to send to 251 * 252 * @param endpointUri the endpoint URI to send to 253 */ 254 FluentProducerTemplate to(String endpointUri); 255 256 /** 257 * Endpoint to send to 258 * 259 * @param endpoint the endpoint to send to 260 */ 261 FluentProducerTemplate to(Endpoint endpoint); 262 263 /** 264 * Send to an endpoint (InOut) returning any result output body. 265 * 266 * @return the result 267 * @throws CamelExecutionException is thrown if error occurred 268 */ 269 Object request() throws CamelExecutionException; 270 271 /** 272 * Send to an endpoint (InOut). 273 * 274 * @param type the expected response type 275 * @return the result 276 * @throws CamelExecutionException is thrown if error occurred 277 */ 278 <T> T request(Class<T> type) throws CamelExecutionException; 279 280 /** 281 * Sends asynchronously to the given endpoint (InOut). 282 * 283 * @return a handle to be used to get the response in the future 284 */ 285 Future<Object> asyncRequest(); 286 287 /** 288 * Sends asynchronously to the given endpoint (InOut). 289 * 290 * @param type the expected response type 291 * @return a handle to be used to get the response in the future 292 */ 293 <T> Future<T> asyncRequest(Class<T> type); 294 295 /** 296 * Send to an endpoint (InOnly) 297 * 298 * @throws CamelExecutionException is thrown if error occurred 299 */ 300 Exchange send() throws CamelExecutionException; 301 302 /** 303 * Sends asynchronously to the given endpoint (InOnly). 304 * 305 * @return a handle to be used to get the response in the future 306 */ 307 Future<Exchange> asyncSend(); 308}