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.Expression; 027import org.apache.camel.model.language.ExpressionDefinition; 028import org.apache.camel.spi.IdempotentRepository; 029import org.apache.camel.spi.Metadata; 030 031/** 032 * Filters out duplicate messages 033 */ 034@Metadata(label = "eip,routing") 035@XmlRootElement(name = "idempotentConsumer") 036@XmlAccessorType(XmlAccessType.FIELD) 037public class IdempotentConsumerDefinition extends OutputExpressionNode { 038 039 @XmlAttribute(required = true) 040 private String messageIdRepositoryRef; 041 @XmlAttribute 042 @Metadata(defaultValue = "true") 043 private Boolean eager; 044 @XmlAttribute 045 private Boolean completionEager; 046 @XmlAttribute 047 @Metadata(defaultValue = "true") 048 private Boolean skipDuplicate; 049 @XmlAttribute 050 @Metadata(defaultValue = "true") 051 private Boolean removeOnFailure; 052 @XmlTransient 053 private IdempotentRepository idempotentRepository; 054 055 public IdempotentConsumerDefinition() { 056 } 057 058 public IdempotentConsumerDefinition(Expression messageIdExpression, IdempotentRepository idempotentRepository) { 059 super(messageIdExpression); 060 this.idempotentRepository = idempotentRepository; 061 } 062 063 @Override 064 public String toString() { 065 return "IdempotentConsumer[" + getExpression() + " -> " + getOutputs() + "]"; 066 } 067 068 @Override 069 public String getShortName() { 070 return "idempotentConsumer"; 071 } 072 073 @Override 074 public String getLabel() { 075 return "idempotentConsumer[" + getExpression() + "]"; 076 } 077 078 // Fluent API 079 // ------------------------------------------------------------------------- 080 081 /** 082 * Sets the reference name of the message id repository 083 * 084 * @param messageIdRepositoryRef the reference name of message id repository 085 * @return builder 086 */ 087 public IdempotentConsumerDefinition messageIdRepositoryRef(String messageIdRepositoryRef) { 088 setMessageIdRepositoryRef(messageIdRepositoryRef); 089 return this; 090 } 091 092 /** 093 * Sets the message id repository for the idempotent consumer 094 * 095 * @param idempotentRepository the repository instance of idempotent 096 * @return builder 097 */ 098 public IdempotentConsumerDefinition messageIdRepository(IdempotentRepository idempotentRepository) { 099 setMessageIdRepository(idempotentRepository); 100 return this; 101 } 102 103 /** 104 * Sets the message id repository for the idempotent consumer 105 * 106 * @param idempotentRepository the repository instance of idempotent 107 * @return builder 108 */ 109 public IdempotentConsumerDefinition messageIdRepository(Supplier<IdempotentRepository> idempotentRepository) { 110 setMessageIdRepository(idempotentRepository.get()); 111 return this; 112 } 113 114 /** 115 * Sets whether to eagerly add the key to the idempotent repository or wait 116 * until the exchange is complete. Eager is default enabled. 117 * 118 * @param eager <tt>true</tt> to add the key before processing, 119 * <tt>false</tt> to wait until the exchange is complete. 120 * @return builder 121 */ 122 public IdempotentConsumerDefinition eager(boolean eager) { 123 setEager(eager); 124 return this; 125 } 126 127 /** 128 * Sets whether to complete the idempotent consumer eager or when the 129 * exchange is done. 130 * <p/> 131 * If this option is <tt>true</tt> to complete eager, then the idempotent 132 * consumer will trigger its completion when the exchange reached the end of 133 * the block of the idempotent consumer pattern. So if the exchange is 134 * continued routed after the block ends, then whatever happens there does 135 * not affect the state. 136 * <p/> 137 * If this option is <tt>false</tt> (default) to <b>not</b> complete eager, 138 * then the idempotent consumer will complete when the exchange is done 139 * being routed. So if the exchange is continued routed after the block 140 * ends, then whatever happens there <b>also</b> affect the state. For 141 * example if the exchange failed due to an exception, then the state of the 142 * idempotent consumer will be a rollback. 143 * 144 * @param completionEager whether to complete eager or complete when the 145 * exchange is done 146 * @return builder 147 */ 148 public IdempotentConsumerDefinition completionEager(boolean completionEager) { 149 setCompletionEager(completionEager); 150 return this; 151 } 152 153 /** 154 * Sets whether to remove or keep the key on failure. 155 * <p/> 156 * The default behavior is to remove the key on failure. 157 * 158 * @param removeOnFailure <tt>true</tt> to remove the key, <tt>false</tt> to 159 * keep the key if the exchange fails. 160 * @return builder 161 */ 162 public IdempotentConsumerDefinition removeOnFailure(boolean removeOnFailure) { 163 setRemoveOnFailure(removeOnFailure); 164 return this; 165 } 166 167 /** 168 * Sets whether to skip duplicates or not. 169 * <p/> 170 * The default behavior is to skip duplicates. 171 * <p/> 172 * A duplicate message would have the Exchange property 173 * {@link org.apache.camel.Exchange#DUPLICATE_MESSAGE} set to a 174 * {@link Boolean#TRUE} value. A none duplicate message will not have this 175 * property set. 176 * 177 * @param skipDuplicate <tt>true</tt> to skip duplicates, <tt>false</tt> to 178 * allow duplicates. 179 * @return builder 180 */ 181 public IdempotentConsumerDefinition skipDuplicate(boolean skipDuplicate) { 182 setSkipDuplicate(skipDuplicate); 183 return this; 184 } 185 186 /** 187 * Expression used to calculate the correlation key to use for duplicate 188 * check. The Exchange which has the same correlation key is regarded as a 189 * duplicate and will be rejected. 190 */ 191 @Override 192 public void setExpression(ExpressionDefinition expression) { 193 // override to include javadoc what the expression is used for 194 super.setExpression(expression); 195 } 196 197 public String getMessageIdRepositoryRef() { 198 return messageIdRepositoryRef; 199 } 200 201 public void setMessageIdRepositoryRef(String messageIdRepositoryRef) { 202 this.messageIdRepositoryRef = messageIdRepositoryRef; 203 } 204 205 public IdempotentRepository getMessageIdRepository() { 206 return idempotentRepository; 207 } 208 209 public void setMessageIdRepository(IdempotentRepository idempotentRepository) { 210 this.idempotentRepository = idempotentRepository; 211 } 212 213 public Boolean getEager() { 214 return eager; 215 } 216 217 public void setEager(Boolean eager) { 218 this.eager = eager; 219 } 220 221 public Boolean getSkipDuplicate() { 222 return skipDuplicate; 223 } 224 225 public void setSkipDuplicate(Boolean skipDuplicate) { 226 this.skipDuplicate = skipDuplicate; 227 } 228 229 public Boolean getRemoveOnFailure() { 230 return removeOnFailure; 231 } 232 233 public void setRemoveOnFailure(Boolean removeOnFailure) { 234 this.removeOnFailure = removeOnFailure; 235 } 236 237 public Boolean getCompletionEager() { 238 return completionEager; 239 } 240 241 public void setCompletionEager(Boolean completionEager) { 242 this.completionEager = completionEager; 243 } 244 245}