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.model; 018 019import java.util.function.Supplier; 020 021import javax.xml.bind.annotation.XmlAccessType; 022import javax.xml.bind.annotation.XmlAccessorType; 023import javax.xml.bind.annotation.XmlAttribute; 024import javax.xml.bind.annotation.XmlRootElement; 025import javax.xml.bind.annotation.XmlTransient; 026 027import org.apache.camel.AggregationStrategy; 028import org.apache.camel.model.language.ExpressionDefinition; 029import org.apache.camel.spi.Metadata; 030 031/** 032 * Enriches messages with data polled from a secondary resource 033 * 034 * @see org.apache.camel.processor.Enricher 035 */ 036@Metadata(label = "eip,transformation") 037@XmlRootElement(name = "pollEnrich") 038@XmlAccessorType(XmlAccessType.FIELD) 039public class PollEnrichDefinition extends ExpressionNode { 040 @XmlAttribute 041 @Metadata(javaType = "java.time.Duration", defaultValue = "-1") 042 private String timeout; 043 @XmlAttribute(name = "strategyRef") 044 private String aggregationStrategyRef; 045 @XmlAttribute(name = "strategyMethodName") 046 private String aggregationStrategyMethodName; 047 @XmlAttribute(name = "strategyMethodAllowNull") 048 @Metadata(javaType = "java.lang.Boolean") 049 private String aggregationStrategyMethodAllowNull; 050 @XmlAttribute 051 @Metadata(javaType = "java.lang.Boolean") 052 private String aggregateOnException; 053 @XmlTransient 054 private AggregationStrategy aggregationStrategy; 055 @XmlAttribute 056 @Metadata(javaType = "java.lang.Integer") 057 private String cacheSize; 058 @XmlAttribute 059 @Metadata(javaType = "java.lang.Integer") 060 private String ignoreInvalidEndpoint; 061 062 public PollEnrichDefinition() { 063 } 064 065 public PollEnrichDefinition(AggregationStrategy aggregationStrategy, long timeout) { 066 this.aggregationStrategy = aggregationStrategy; 067 this.timeout = Long.toString(timeout); 068 } 069 070 @Override 071 public String toString() { 072 return "PollEnrich[" + getExpression() + "]"; 073 } 074 075 @Override 076 public String getShortName() { 077 return "pollEnrich"; 078 } 079 080 @Override 081 public String getLabel() { 082 return "pollEnrich[" + getExpression() + "]"; 083 } 084 085 // Fluent API 086 // ------------------------------------------------------------------------- 087 088 /** 089 * Timeout in millis when polling from the external service. 090 * <p/> 091 * The timeout has influence about the poll enrich behavior. It basically 092 * operations in three different modes: 093 * <ul> 094 * <li>negative value - Waits until a message is available and then returns 095 * it. Warning that this method could block indefinitely if no messages are 096 * available.</li> 097 * <li>0 - Attempts to receive a message exchange immediately without 098 * waiting and returning <tt>null</tt> if a message exchange is not 099 * available yet.</li> 100 * <li>positive value - Attempts to receive a message exchange, waiting up 101 * to the given timeout to expire if a message is not yet available. Returns 102 * <tt>null</tt> if timed out</li> 103 * </ul> 104 * The default value is -1 and therefore the method could block 105 * indefinitely, and therefore its recommended to use a timeout value 106 */ 107 public PollEnrichDefinition timeout(long timeout) { 108 setTimeout(Long.toString(timeout)); 109 return this; 110 } 111 112 /** 113 * Sets the AggregationStrategy to be used to merge the reply from the 114 * external service, into a single outgoing message. By default Camel will 115 * use the reply from the external service as outgoing message. 116 */ 117 public PollEnrichDefinition aggregationStrategy(AggregationStrategy aggregationStrategy) { 118 setAggregationStrategy(aggregationStrategy); 119 return this; 120 } 121 122 /** 123 * Sets the AggregationStrategy to be used to merge the reply from the 124 * external service, into a single outgoing message. By default Camel will 125 * use the reply from the external service as outgoing message. 126 */ 127 public PollEnrichDefinition aggregationStrategy(Supplier<AggregationStrategy> aggregationStrategy) { 128 setAggregationStrategy(aggregationStrategy.get()); 129 return this; 130 } 131 132 /** 133 * Refers to an AggregationStrategy to be used to merge the reply from the 134 * external service, into a single outgoing message. By default Camel will 135 * use the reply from the external service as outgoing message. 136 */ 137 public PollEnrichDefinition aggregationStrategyRef(String aggregationStrategyRef) { 138 setAggregationStrategyRef(aggregationStrategyRef); 139 return this; 140 } 141 142 /** 143 * This option can be used to explicit declare the method name to use, when 144 * using POJOs as the AggregationStrategy. 145 */ 146 public PollEnrichDefinition aggregationStrategyMethodName(String aggregationStrategyMethodName) { 147 setAggregationStrategyMethodName(aggregationStrategyMethodName); 148 return this; 149 } 150 151 /** 152 * If this option is false then the aggregate method is not used if there 153 * was no data to enrich. If this option is true then null values is used as 154 * the oldExchange (when no data to enrich), when using POJOs as the 155 * AggregationStrategy. 156 */ 157 public PollEnrichDefinition aggregationStrategyMethodAllowNull(boolean aggregationStrategyMethodAllowNull) { 158 setAggregationStrategyMethodAllowNull(Boolean.toString(aggregationStrategyMethodAllowNull)); 159 return this; 160 } 161 162 /** 163 * If this option is false then the aggregate method is not used if there 164 * was an exception thrown while trying to retrieve the data to enrich from 165 * the resource. Setting this option to true allows end users to control 166 * what to do if there was an exception in the aggregate method. For example 167 * to suppress the exception or set a custom message body etc. 168 */ 169 public PollEnrichDefinition aggregateOnException(boolean aggregateOnException) { 170 setAggregateOnException(Boolean.toString(aggregateOnException)); 171 return this; 172 } 173 174 /** 175 * Sets the maximum size used by the 176 * {@link org.apache.camel.spi.ConsumerCache} which is used to cache and 177 * reuse consumers when uris are reused. 178 * 179 * Beware that when using dynamic endpoints then it affects how well the cache can be utilized. 180 * If each dynamic endpoint is unique then its best to turn of caching by setting this to -1, which 181 * allows Camel to not cache both the producers and endpoints; they are regarded as prototype scoped 182 * and will be stopped and discarded after use. This reduces memory usage as otherwise producers/endpoints 183 * are stored in memory in the caches. 184 * 185 * However if there are a high degree of dynamic endpoints that have been used before, then it can 186 * benefit to use the cache to reuse both producers and endpoints and therefore the cache size 187 * can be set accordingly or rely on the default size (1000). 188 * 189 * If there is a mix of unique and used before dynamic endpoints, then setting a reasonable cache size 190 * can help reduce memory usage to avoid storing too many non frequent used producers. 191 * 192 * @param cacheSize the cache size, use <tt>0</tt> for default cache size, 193 * or <tt>-1</tt> to turn cache off. 194 * @return the builder 195 */ 196 public PollEnrichDefinition cacheSize(int cacheSize) { 197 setCacheSize(Integer.toString(cacheSize)); 198 return this; 199 } 200 201 /** 202 * Sets the maximum size used by the 203 * {@link org.apache.camel.spi.ConsumerCache} which is used to cache and 204 * reuse consumers when uris are reused. 205 * 206 * Beware that when using dynamic endpoints then it affects how well the cache can be utilized. 207 * If each dynamic endpoint is unique then its best to turn of caching by setting this to -1, which 208 * allows Camel to not cache both the producers and endpoints; they are regarded as prototype scoped 209 * and will be stopped and discarded after use. This reduces memory usage as otherwise producers/endpoints 210 * are stored in memory in the caches. 211 * 212 * However if there are a high degree of dynamic endpoints that have been used before, then it can 213 * benefit to use the cache to reuse both producers and endpoints and therefore the cache size 214 * can be set accordingly or rely on the default size (1000). 215 * 216 * If there is a mix of unique and used before dynamic endpoints, then setting a reasonable cache size 217 * can help reduce memory usage to avoid storing too many non frequent used producers. 218 * 219 * @param cacheSize the cache size, use <tt>0</tt> for default cache size, 220 * or <tt>-1</tt> to turn cache off. 221 * @return the builder 222 */ 223 public PollEnrichDefinition cacheSize(String cacheSize) { 224 setCacheSize(cacheSize); 225 return this; 226 } 227 228 /** 229 * Ignore the invalidate endpoint exception when try to create a producer 230 * with that endpoint 231 * 232 * @return the builder 233 */ 234 public PollEnrichDefinition ignoreInvalidEndpoint() { 235 setIgnoreInvalidEndpoint(Boolean.toString(true)); 236 return this; 237 } 238 239 // Properties 240 // ------------------------------------------------------------------------- 241 242 /** 243 * Expression that computes the endpoint uri to use as the resource endpoint 244 * to enrich from 245 */ 246 @Override 247 public void setExpression(ExpressionDefinition expression) { 248 // override to include javadoc what the expression is used for 249 super.setExpression(expression); 250 } 251 252 public String getTimeout() { 253 return timeout; 254 } 255 256 public void setTimeout(String timeout) { 257 this.timeout = timeout; 258 } 259 260 public String getAggregationStrategyRef() { 261 return aggregationStrategyRef; 262 } 263 264 public void setAggregationStrategyRef(String aggregationStrategyRef) { 265 this.aggregationStrategyRef = aggregationStrategyRef; 266 } 267 268 public String getAggregationStrategyMethodName() { 269 return aggregationStrategyMethodName; 270 } 271 272 public void setAggregationStrategyMethodName(String aggregationStrategyMethodName) { 273 this.aggregationStrategyMethodName = aggregationStrategyMethodName; 274 } 275 276 public String getAggregationStrategyMethodAllowNull() { 277 return aggregationStrategyMethodAllowNull; 278 } 279 280 public void setAggregationStrategyMethodAllowNull(String aggregationStrategyMethodAllowNull) { 281 this.aggregationStrategyMethodAllowNull = aggregationStrategyMethodAllowNull; 282 } 283 284 public AggregationStrategy getAggregationStrategy() { 285 return aggregationStrategy; 286 } 287 288 public void setAggregationStrategy(AggregationStrategy aggregationStrategy) { 289 this.aggregationStrategy = aggregationStrategy; 290 } 291 292 public String getAggregateOnException() { 293 return aggregateOnException; 294 } 295 296 public void setAggregateOnException(String aggregateOnException) { 297 this.aggregateOnException = aggregateOnException; 298 } 299 300 public String getCacheSize() { 301 return cacheSize; 302 } 303 304 public void setCacheSize(String cacheSize) { 305 this.cacheSize = cacheSize; 306 } 307 308 public String getIgnoreInvalidEndpoint() { 309 return ignoreInvalidEndpoint; 310 } 311 312 public void setIgnoreInvalidEndpoint(String ignoreInvalidEndpoint) { 313 this.ignoreInvalidEndpoint = ignoreInvalidEndpoint; 314 } 315}