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