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