org.apache.camel.processor.ClaimCheckProcessor Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.processor;
import org.apache.camel.AggregationStrategy;
import org.apache.camel.AsyncCallback;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.impl.engine.DefaultClaimCheckRepository;
import org.apache.camel.spi.ClaimCheckRepository;
import org.apache.camel.spi.IdAware;
import org.apache.camel.spi.RouteIdAware;
import org.apache.camel.support.AsyncProcessorSupport;
import org.apache.camel.support.ExchangeHelper;
import org.apache.camel.support.LanguageSupport;
import org.apache.camel.support.service.ServiceHelper;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ClaimCheck EIP implementation.
*
* The current Claim Check EIP implementation in Camel is only intended for temporary memory repository. Likewise
* the repository is not shared among {@link Exchange}s, but a private instance is created per {@link Exchange}.
* This guards against concurrent and thread-safe issues. For off-memory persistent storage of data, then use
* any of the many Camel components that support persistent storage, and do not use this Claim Check EIP implementation.
*/
public class ClaimCheckProcessor extends AsyncProcessorSupport implements IdAware, RouteIdAware, CamelContextAware {
private static final Logger LOG = LoggerFactory.getLogger(ClaimCheckProcessor.class);
private CamelContext camelContext;
private String id;
private String routeId;
private String operation;
private AggregationStrategy aggregationStrategy;
private String key;
private Expression keyExpression;
private String filter;
@Override
public CamelContext getCamelContext() {
return camelContext;
}
@Override
public void setCamelContext(CamelContext camelContext) {
this.camelContext = camelContext;
}
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
@Override
public String getRouteId() {
return routeId;
}
@Override
public void setRouteId(String routeId) {
this.routeId = routeId;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
public AggregationStrategy getAggregationStrategy() {
return aggregationStrategy;
}
public void setAggregationStrategy(AggregationStrategy aggregationStrategy) {
this.aggregationStrategy = aggregationStrategy;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getFilter() {
return filter;
}
public void setFilter(String filter) {
this.filter = filter;
}
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
// the repository is scoped per exchange
ClaimCheckRepository repo = exchange.getProperty(Exchange.CLAIM_CHECK_REPOSITORY, ClaimCheckRepository.class);
if (repo == null) {
repo = new DefaultClaimCheckRepository();
exchange.setProperty(Exchange.CLAIM_CHECK_REPOSITORY, repo);
}
try {
String claimKey = keyExpression.evaluate(exchange, String.class);
if ("Set".equals(operation)) {
// copy exchange, and do not share the unit of work
Exchange copy = ExchangeHelper.createCorrelatedCopy(exchange, false);
boolean addedNew = repo.add(claimKey, copy);
if (addedNew) {
LOG.debug("Add: {} -> {}", claimKey, copy);
} else {
LOG.debug("Override: {} -> {}", claimKey, copy);
}
} else if ("Get".equals(operation)) {
Exchange copy = repo.get(claimKey);
LOG.debug("Get: {} -> {}", claimKey, exchange);
if (copy != null) {
Exchange result = aggregationStrategy.aggregate(exchange, copy);
if (result != null) {
ExchangeHelper.copyResultsPreservePattern(exchange, result);
}
}
} else if ("GetAndRemove".equals(operation)) {
Exchange copy = repo.getAndRemove(claimKey);
LOG.debug("GetAndRemove: {} -> {}", claimKey, exchange);
if (copy != null) {
// prepare the exchanges for aggregation
ExchangeHelper.prepareAggregation(exchange, copy);
Exchange result = aggregationStrategy.aggregate(exchange, copy);
if (result != null) {
ExchangeHelper.copyResultsPreservePattern(exchange, result);
}
}
} else if ("Push".equals(operation)) {
// copy exchange, and do not share the unit of work
Exchange copy = ExchangeHelper.createCorrelatedCopy(exchange, false);
LOG.debug("Push: {} -> {}", claimKey, copy);
repo.push(copy);
} else if ("Pop".equals(operation)) {
Exchange copy = repo.pop();
LOG.debug("Pop: {} -> {}", claimKey, exchange);
if (copy != null) {
// prepare the exchanges for aggregation
ExchangeHelper.prepareAggregation(exchange, copy);
Exchange result = aggregationStrategy.aggregate(exchange, copy);
if (result != null) {
ExchangeHelper.copyResultsPreservePattern(exchange, result);
}
}
}
} catch (Throwable e) {
exchange.setException(e);
}
callback.done(true);
return true;
}
@Override
protected void doStart() throws Exception {
ObjectHelper.notNull(operation, "operation", this);
if (aggregationStrategy == null) {
aggregationStrategy = createAggregationStrategy();
}
if (aggregationStrategy instanceof CamelContextAware) {
((CamelContextAware) aggregationStrategy).setCamelContext(camelContext);
}
if (LanguageSupport.hasSimpleFunction(key)) {
keyExpression = camelContext.resolveLanguage("simple").createExpression(key);
} else {
keyExpression = camelContext.resolveLanguage("constant").createExpression(key);
}
ServiceHelper.startService(aggregationStrategy);
}
@Override
protected void doStop() throws Exception {
ServiceHelper.stopService(aggregationStrategy);
}
@Override
public String toString() {
return id;
}
protected AggregationStrategy createAggregationStrategy() {
ClaimCheckAggregationStrategy answer = new ClaimCheckAggregationStrategy();
answer.setFilter(filter);
return answer;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy