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