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.processor; 018 019import org.apache.camel.AsyncCallback; 020import org.apache.camel.AsyncProcessor; 021import org.apache.camel.CamelContext; 022import org.apache.camel.CamelContextAware; 023import org.apache.camel.Exchange; 024import org.apache.camel.impl.DefaultClaimCheckRepository; 025import org.apache.camel.processor.aggregate.AggregationStrategy; 026import org.apache.camel.spi.ClaimCheckRepository; 027import org.apache.camel.spi.IdAware; 028import org.apache.camel.support.ServiceSupport; 029import org.apache.camel.util.AsyncProcessorHelper; 030import org.apache.camel.util.ExchangeHelper; 031import org.apache.camel.util.ObjectHelper; 032import org.apache.camel.util.ServiceHelper; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036/** 037 * ClaimCheck EIP implementation. 038 * <p/> 039 * The current Claim Check EIP implementation in Camel is only intended for temporary memory repository. Likewise 040 * the repository is not shared among {@link Exchange}s, but a private instance is created per {@link Exchange}. 041 * This guards against concurrent and thread-safe issues. For off-memory persistent storage of data, then use 042 * any of the many Camel components that support persistent storage, and do not use this Claim Check EIP implementation. 043 */ 044public class ClaimCheckProcessor extends ServiceSupport implements AsyncProcessor, IdAware, CamelContextAware { 045 046 private static final Logger LOG = LoggerFactory.getLogger(ClaimCheckProcessor.class); 047 private CamelContext camelContext; 048 private String id; 049 private String operation; 050 private AggregationStrategy aggregationStrategy; 051 private String key; 052 private String filter; 053 054 @Override 055 public CamelContext getCamelContext() { 056 return camelContext; 057 } 058 059 @Override 060 public void setCamelContext(CamelContext camelContext) { 061 this.camelContext = camelContext; 062 } 063 064 @Override 065 public String getId() { 066 return id; 067 } 068 069 @Override 070 public void setId(String id) { 071 this.id = id; 072 } 073 074 public String getOperation() { 075 return operation; 076 } 077 078 public void setOperation(String operation) { 079 this.operation = operation; 080 } 081 082 public AggregationStrategy getAggregationStrategy() { 083 return aggregationStrategy; 084 } 085 086 public void setAggregationStrategy(AggregationStrategy aggregationStrategy) { 087 this.aggregationStrategy = aggregationStrategy; 088 } 089 090 public String getKey() { 091 return key; 092 } 093 094 public void setKey(String key) { 095 this.key = key; 096 } 097 098 public String getFilter() { 099 return filter; 100 } 101 102 public void setFilter(String filter) { 103 this.filter = filter; 104 } 105 106 public void process(Exchange exchange) throws Exception { 107 AsyncProcessorHelper.process(this, exchange); 108 } 109 110 @Override 111 public boolean process(Exchange exchange, AsyncCallback callback) { 112 // the repository is scoped per exchange 113 ClaimCheckRepository repo = exchange.getProperty(Exchange.CLAIM_CHECK_REPOSITORY, ClaimCheckRepository.class); 114 if (repo == null) { 115 repo = new DefaultClaimCheckRepository(); 116 exchange.setProperty(Exchange.CLAIM_CHECK_REPOSITORY, repo); 117 } 118 119 try { 120 if ("Set".equals(operation)) { 121 // copy exchange, and do not share the unit of work 122 Exchange copy = ExchangeHelper.createCorrelatedCopy(exchange, false); 123 boolean addedNew = repo.add(key, copy); 124 if (addedNew) { 125 LOG.debug("Add: {} -> {}", key, copy); 126 } else { 127 LOG.debug("Override: {} -> {}", key, copy); 128 } 129 } else if ("Get".equals(operation)) { 130 Exchange copy = repo.get(key); 131 LOG.debug("Get: {} -> {}", key, exchange); 132 if (copy != null) { 133 Exchange result = aggregationStrategy.aggregate(exchange, copy); 134 if (result != null) { 135 ExchangeHelper.copyResultsPreservePattern(exchange, result); 136 } 137 } 138 } else if ("GetAndRemove".equals(operation)) { 139 Exchange copy = repo.getAndRemove(key); 140 LOG.debug("GetAndRemove: {} -> {}", key, exchange); 141 if (copy != null) { 142 // prepare the exchanges for aggregation 143 ExchangeHelper.prepareAggregation(exchange, copy); 144 Exchange result = aggregationStrategy.aggregate(exchange, copy); 145 if (result != null) { 146 ExchangeHelper.copyResultsPreservePattern(exchange, result); 147 } 148 } 149 } else if ("Push".equals(operation)) { 150 // copy exchange, and do not share the unit of work 151 Exchange copy = ExchangeHelper.createCorrelatedCopy(exchange, false); 152 LOG.debug("Push: {} -> {}", key, copy); 153 repo.push(copy); 154 } else if ("Pop".equals(operation)) { 155 Exchange copy = repo.pop(); 156 LOG.debug("Pop: {} -> {}", key, exchange); 157 if (copy != null) { 158 // prepare the exchanges for aggregation 159 ExchangeHelper.prepareAggregation(exchange, copy); 160 Exchange result = aggregationStrategy.aggregate(exchange, copy); 161 if (result != null) { 162 ExchangeHelper.copyResultsPreservePattern(exchange, result); 163 } 164 } 165 } 166 } catch (Throwable e) { 167 exchange.setException(e); 168 } 169 170 callback.done(true); 171 return true; 172 } 173 174 @Override 175 protected void doStart() throws Exception { 176 ObjectHelper.notNull(operation, "operation", this); 177 178 if (aggregationStrategy == null) { 179 aggregationStrategy = createAggregationStrategy(); 180 } 181 if (aggregationStrategy instanceof CamelContextAware) { 182 ((CamelContextAware) aggregationStrategy).setCamelContext(camelContext); 183 } 184 185 ServiceHelper.startServices(aggregationStrategy); 186 } 187 188 @Override 189 protected void doStop() throws Exception { 190 ServiceHelper.stopServices(aggregationStrategy); 191 } 192 193 @Override 194 public String toString() { 195 return "ClaimCheck[" + operation + "]"; 196 } 197 198 protected AggregationStrategy createAggregationStrategy() { 199 ClaimCheckAggregationStrategy answer = new ClaimCheckAggregationStrategy(); 200 answer.setFilter(filter); 201 return answer; 202 } 203}