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.Collections; 020import java.util.List; 021 022import javax.xml.bind.annotation.XmlAccessType; 023import javax.xml.bind.annotation.XmlAccessorType; 024import javax.xml.bind.annotation.XmlAttribute; 025import javax.xml.bind.annotation.XmlRootElement; 026 027import org.apache.camel.Expression; 028import org.apache.camel.model.language.ExpressionDefinition; 029import org.apache.camel.spi.Metadata; 030 031/** 032 * Routes messages based on dynamic rules 033 */ 034@Metadata(label = "eip,endpoint,routing") 035@XmlRootElement(name = "dynamicRouter") 036@XmlAccessorType(XmlAccessType.FIELD) 037public class DynamicRouterDefinition<Type extends ProcessorDefinition<Type>> extends ExpressionNode { 038 039 public static final String DEFAULT_DELIMITER = ","; 040 041 @XmlAttribute 042 @Metadata(defaultValue = ",") 043 private String uriDelimiter; 044 @XmlAttribute 045 private String ignoreInvalidEndpoints; 046 @XmlAttribute 047 @Metadata(javaType = "java.lang.Integer") 048 private String cacheSize; 049 050 public DynamicRouterDefinition() { 051 } 052 053 public DynamicRouterDefinition(Expression expression) { 054 super(expression); 055 } 056 057 @Override 058 public String toString() { 059 return "DynamicRouter[" + getExpression() + "]"; 060 } 061 062 @Override 063 public String getShortName() { 064 return "dynamicRouter"; 065 } 066 067 @Override 068 public String getLabel() { 069 return "dynamicRouter[" + getExpression() + "]"; 070 } 071 072 @Override 073 public List<ProcessorDefinition<?>> getOutputs() { 074 return Collections.emptyList(); 075 } 076 077 /** 078 * Expression to call that returns the endpoint(s) to route to in the 079 * dynamic routing. 080 * <p/> 081 * <b>Important:</b> The expression will be called in a while loop fashion, 082 * until the expression returns <tt>null</tt> which means the dynamic router 083 * is finished. 084 */ 085 @Override 086 public void setExpression(ExpressionDefinition expression) { 087 // override to include javadoc what the expression is used for 088 super.setExpression(expression); 089 } 090 091 public void setUriDelimiter(String uriDelimiter) { 092 this.uriDelimiter = uriDelimiter; 093 } 094 095 public String getUriDelimiter() { 096 return uriDelimiter; 097 } 098 099 public void setIgnoreInvalidEndpoints(String ignoreInvalidEndpoints) { 100 this.ignoreInvalidEndpoints = ignoreInvalidEndpoints; 101 } 102 103 public String getIgnoreInvalidEndpoints() { 104 return ignoreInvalidEndpoints; 105 } 106 107 // Fluent API 108 // ------------------------------------------------------------------------- 109 110 public String getCacheSize() { 111 return cacheSize; 112 } 113 114 public void setCacheSize(String cacheSize) { 115 this.cacheSize = cacheSize; 116 } 117 118 @Override 119 @SuppressWarnings("unchecked") 120 public Type end() { 121 // allow end() to return to previous type so you can continue in the DSL 122 return (Type)super.end(); 123 } 124 125 /** 126 * Ignore the invalidate endpoint exception when try to create a producer 127 * with that endpoint 128 * 129 * @return the builder 130 */ 131 public DynamicRouterDefinition<Type> ignoreInvalidEndpoints() { 132 setIgnoreInvalidEndpoints(Boolean.toString(true)); 133 return this; 134 } 135 136 /** 137 * Sets the uri delimiter to use 138 * 139 * @param uriDelimiter the delimiter 140 * @return the builder 141 */ 142 public DynamicRouterDefinition<Type> uriDelimiter(String uriDelimiter) { 143 setUriDelimiter(uriDelimiter); 144 return this; 145 } 146 147 /** 148 * Sets the maximum size used by the 149 * {@link org.apache.camel.spi.ProducerCache} which is used to cache and 150 * reuse producers when using this dynamic router, when uris are reused. 151 * 152 * Beware that when using dynamic endpoints then it affects how well the cache can be utilized. 153 * If each dynamic endpoint is unique then its best to turn of caching by setting this to -1, which 154 * allows Camel to not cache both the producers and endpoints; they are regarded as prototype scoped 155 * and will be stopped and discarded after use. This reduces memory usage as otherwise producers/endpoints 156 * are stored in memory in the caches. 157 * 158 * However if there are a high degree of dynamic endpoints that have been used before, then it can 159 * benefit to use the cache to reuse both producers and endpoints and therefore the cache size 160 * can be set accordingly or rely on the default size (1000). 161 * 162 * If there is a mix of unique and used before dynamic endpoints, then setting a reasonable cache size 163 * can help reduce memory usage to avoid storing too many non frequent used producers. 164 * 165 * @param cacheSize the cache size, use <tt>0</tt> for default cache size, 166 * or <tt>-1</tt> to turn cache off. 167 * @return the builder 168 */ 169 public DynamicRouterDefinition<Type> cacheSize(int cacheSize) { 170 setCacheSize(Integer.toString(cacheSize)); 171 return this; 172 } 173 174 /** 175 * Sets the maximum size used by the 176 * {@link org.apache.camel.spi.ProducerCache} which is used to cache and 177 * reuse producers when using this dynamic router, 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 DynamicRouterDefinition<Type> cacheSize(String cacheSize) { 197 setCacheSize(cacheSize); 198 return this; 199 } 200 201}