use of org.apache.camel.CamelExchangeException in project camel by apache.
the class DefaultAhcBinding method populateBody.
protected void populateBody(RequestBuilder builder, AhcEndpoint endpoint, Exchange exchange) throws CamelExchangeException {
Message in = exchange.getIn();
if (in.getBody() == null) {
return;
}
String contentType = ExchangeHelper.getContentType(exchange);
BodyGenerator body = in.getBody(BodyGenerator.class);
String charset = IOHelper.getCharsetName(exchange, false);
if (body == null) {
try {
Object data = in.getBody();
if (data != null) {
if (contentType != null && AhcConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
if (!endpoint.getComponent().isAllowJavaSerializedObject()) {
throw new CamelExchangeException("Content-type " + AhcConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT + " is not allowed", exchange);
}
// serialized java object
Serializable obj = in.getMandatoryBody(Serializable.class);
// write object to output stream
ByteArrayOutputStream bos = new ByteArrayOutputStream(endpoint.getBufferSize());
AhcHelper.writeObjectToStream(bos, obj);
byte[] bytes = bos.toByteArray();
body = new ByteArrayBodyGenerator(bytes);
IOHelper.close(bos);
} else if (data instanceof File || data instanceof GenericFile) {
// file based (could potentially also be a FTP file etc)
File file = in.getBody(File.class);
if (file != null) {
body = new FileBodyGenerator(file);
}
} else if (data instanceof String) {
// (for example application/x-www-form-urlencoded forms being sent)
if (charset != null) {
body = new ByteArrayBodyGenerator(((String) data).getBytes(charset));
} else {
body = new ByteArrayBodyGenerator(((String) data).getBytes());
}
}
// fallback as input stream
if (body == null) {
// force the body as an input stream since this is the fallback
InputStream is = in.getMandatoryBody(InputStream.class);
body = new InputStreamBodyGenerator(is);
}
}
} catch (UnsupportedEncodingException e) {
throw new CamelExchangeException("Error creating BodyGenerator from message body", exchange, e);
} catch (IOException e) {
throw new CamelExchangeException("Error serializing message body", exchange, e);
}
}
if (body != null) {
log.trace("Setting body {}", body);
builder.setBody(body);
}
if (charset != null) {
log.trace("Setting body charset {}", charset);
builder.setCharset(Charset.forName(charset));
}
// must set content type, even if its null, otherwise it may default to
// application/x-www-form-urlencoded which may not be your intention
log.trace("Setting Content-Type {}", contentType);
if (ObjectHelper.isNotEmpty(contentType)) {
builder.setHeader(Exchange.CONTENT_TYPE, contentType);
}
}
use of org.apache.camel.CamelExchangeException in project camel by apache.
the class DefaultAhcBinding method prepareRequest.
public Request prepareRequest(AhcEndpoint endpoint, Exchange exchange) throws CamelExchangeException {
if (endpoint.isBridgeEndpoint()) {
exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
// Need to remove the Host key as it should be not used
exchange.getIn().getHeaders().remove("host");
}
RequestBuilder builder = new RequestBuilder();
URI uri;
try {
// creating the url to use takes 2-steps
String url = AhcHelper.createURL(exchange, endpoint);
uri = AhcHelper.createURI(exchange, url, endpoint);
// get the url from the uri
url = uri.toASCIIString();
log.trace("Setting url {}", url);
builder.setUrl(url);
} catch (Exception e) {
throw new CamelExchangeException("Error creating URL", exchange, e);
}
String method = extractMethod(exchange);
log.trace("Setting method {}", method);
builder.setMethod(method);
populateHeaders(builder, endpoint, exchange);
populateCookieHeaders(builder, endpoint, exchange, uri);
populateBody(builder, endpoint, exchange);
return builder.build();
}
use of org.apache.camel.CamelExchangeException in project camel by apache.
the class DefaultAhcBinding method onHeadersReceived.
@Override
public void onHeadersReceived(AhcEndpoint endpoint, Exchange exchange, HttpResponseHeaders headers) throws Exception {
List<Entry<String, String>> l = headers.getHeaders().entries();
Map<String, List<String>> m = new HashMap<String, List<String>>();
for (Entry<String, String> entry : headers.getHeaders().entries()) {
String key = entry.getKey();
String value = entry.getValue();
m.put(key, Collections.singletonList(value));
exchange.getOut().getHeaders().put(key, value);
}
// handle cookies
if (endpoint.getCookieHandler() != null) {
try {
// creating the url to use takes 2-steps
String url = AhcHelper.createURL(exchange, endpoint);
URI uri = AhcHelper.createURI(exchange, url, endpoint);
endpoint.getCookieHandler().storeCookies(exchange, uri, m);
} catch (Exception e) {
throw new CamelExchangeException("Error storing cookies", exchange, e);
}
}
}
use of org.apache.camel.CamelExchangeException in project camel by apache.
the class MulticastProcessor method doProcessParallel.
protected void doProcessParallel(final Exchange original, final AtomicExchange result, final Iterable<ProcessorExchangePair> pairs, final boolean streaming, final AsyncCallback callback) throws Exception {
ObjectHelper.notNull(executorService, "ExecutorService", this);
ObjectHelper.notNull(aggregateExecutorService, "AggregateExecutorService", this);
final CompletionService<Exchange> completion;
if (streaming) {
// execute tasks in parallel+streaming and aggregate in the order they are finished (out of order sequence)
completion = new ExecutorCompletionService<Exchange>(executorService);
} else {
// execute tasks in parallel and aggregate in the order the tasks are submitted (in order sequence)
completion = new SubmitOrderedCompletionService<Exchange>(executorService);
}
final AtomicInteger total = new AtomicInteger(0);
final Iterator<ProcessorExchangePair> it = pairs.iterator();
if (it.hasNext()) {
// when parallel then aggregate on the fly
final AtomicBoolean running = new AtomicBoolean(true);
final AtomicBoolean allTasksSubmitted = new AtomicBoolean();
final CountDownLatch aggregationOnTheFlyDone = new CountDownLatch(1);
final AtomicException executionException = new AtomicException();
// issue task to execute in separate thread so it can aggregate on-the-fly
// while we submit new tasks, and those tasks complete concurrently
// this allows us to optimize work and reduce memory consumption
final AggregateOnTheFlyTask aggregateOnTheFlyTask = new AggregateOnTheFlyTask(result, original, total, completion, running, aggregationOnTheFlyDone, allTasksSubmitted, executionException);
final AtomicBoolean aggregationTaskSubmitted = new AtomicBoolean();
LOG.trace("Starting to submit parallel tasks");
while (it.hasNext()) {
final ProcessorExchangePair pair = it.next();
// in case the iterator returns null then continue to next
if (pair == null) {
continue;
}
final Exchange subExchange = pair.getExchange();
updateNewExchange(subExchange, total.intValue(), pairs, it);
completion.submit(new Callable<Exchange>() {
public Exchange call() throws Exception {
// start the aggregation task at this stage only in order not to pile up too many threads
if (aggregationTaskSubmitted.compareAndSet(false, true)) {
// but only submit the aggregation task once
aggregateExecutorService.submit(aggregateOnTheFlyTask);
}
if (!running.get()) {
// do not start processing the task if we are not running
return subExchange;
}
try {
doProcessParallel(pair);
} catch (Throwable e) {
subExchange.setException(e);
}
// Decide whether to continue with the multicast or not; similar logic to the Pipeline
Integer number = getExchangeIndex(subExchange);
boolean continueProcessing = PipelineHelper.continueProcessing(subExchange, "Parallel processing failed for number " + number, LOG);
if (stopOnException && !continueProcessing) {
// signal to stop running
running.set(false);
// throw caused exception
if (subExchange.getException() != null) {
// wrap in exception to explain where it failed
CamelExchangeException cause = new CamelExchangeException("Parallel processing failed for number " + number, subExchange, subExchange.getException());
subExchange.setException(cause);
}
}
LOG.trace("Parallel processing complete for exchange: {}", subExchange);
return subExchange;
}
});
total.incrementAndGet();
}
// signal all tasks has been submitted
LOG.trace("Signaling that all {} tasks has been submitted.", total.get());
allTasksSubmitted.set(true);
// its to hard to do parallel async routing so we let the caller thread be synchronously
// and have it pickup the replies and do the aggregation (eg we use a latch to wait)
// wait for aggregation to be done
LOG.debug("Waiting for on-the-fly aggregation to complete aggregating {} responses for exchangeId: {}", total.get(), original.getExchangeId());
aggregationOnTheFlyDone.await();
// did we fail for whatever reason, if so throw that caused exception
if (executionException.get() != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Parallel processing failed due {}", executionException.get().getMessage());
}
throw executionException.get();
}
}
// no everything is okay so we are done
LOG.debug("Done parallel processing {} exchanges", total);
}
use of org.apache.camel.CamelExchangeException in project camel by apache.
the class AggregateProcessor method doAggregation.
/**
* Aggregates the exchange with the given correlation key
* <p/>
* This method <b>must</b> be run synchronized as we cannot aggregate the same correlation key
* in parallel.
* <p/>
* The returned {@link Exchange} should be send downstream using the {@link #onSubmitCompletion(String, org.apache.camel.Exchange)}
* method which sends out the aggregated and completed {@link Exchange}.
*
* @param key the correlation key
* @param newExchange the exchange
* @return the aggregated exchange(s) which is complete, or <tt>null</tt> if not yet complete
* @throws org.apache.camel.CamelExchangeException is thrown if error aggregating
*/
private List<Exchange> doAggregation(String key, Exchange newExchange) throws CamelExchangeException {
LOG.trace("onAggregation +++ start +++ with correlation key: {}", key);
List<Exchange> list = new ArrayList<Exchange>();
String complete = null;
Exchange answer;
Exchange originalExchange = aggregationRepository.get(newExchange.getContext(), key);
Exchange oldExchange = originalExchange;
Integer size = 1;
if (oldExchange != null) {
// working when using an identify based approach for optimistic locking like the MemoryAggregationRepository.
if (optimisticLocking && aggregationRepository instanceof MemoryAggregationRepository) {
oldExchange = originalExchange.copy();
}
size = oldExchange.getProperty(Exchange.AGGREGATED_SIZE, 0, Integer.class);
size++;
}
// prepare the exchanges for aggregation
ExchangeHelper.prepareAggregation(oldExchange, newExchange);
// check if we are pre complete
if (preCompletion) {
try {
// put the current aggregated size on the exchange so its avail during completion check
newExchange.setProperty(Exchange.AGGREGATED_SIZE, size);
complete = isPreCompleted(key, oldExchange, newExchange);
// make sure to track timeouts if not complete
if (complete == null) {
trackTimeout(key, newExchange);
}
// remove it afterwards
newExchange.removeProperty(Exchange.AGGREGATED_SIZE);
} catch (Throwable e) {
// must catch any exception from aggregation
throw new CamelExchangeException("Error occurred during preComplete", newExchange, e);
}
} else if (isEagerCheckCompletion()) {
// put the current aggregated size on the exchange so its avail during completion check
newExchange.setProperty(Exchange.AGGREGATED_SIZE, size);
complete = isCompleted(key, newExchange);
// make sure to track timeouts if not complete
if (complete == null) {
trackTimeout(key, newExchange);
}
// remove it afterwards
newExchange.removeProperty(Exchange.AGGREGATED_SIZE);
}
if (preCompletion && complete != null) {
// need to pre complete the current group before we aggregate
doAggregationComplete(complete, list, key, originalExchange, oldExchange);
// as we complete the current group eager, we should indicate the new group is not complete
complete = null;
// and clear old/original exchange as we start on a new group
oldExchange = null;
originalExchange = null;
// and reset the size to 1
size = 1;
// make sure to track timeout as we just restart the correlation group when we are in pre completion mode
trackTimeout(key, newExchange);
}
// aggregate the exchanges
try {
answer = onAggregation(oldExchange, newExchange);
} catch (Throwable e) {
// must catch any exception from aggregation
throw new CamelExchangeException("Error occurred during aggregation", newExchange, e);
}
if (answer == null) {
throw new CamelExchangeException("AggregationStrategy " + aggregationStrategy + " returned null which is not allowed", newExchange);
}
// special for some repository implementations
if (aggregationRepository instanceof RecoverableAggregationRepository) {
boolean valid = oldExchange == null || answer.getExchangeId().equals(oldExchange.getExchangeId());
if (!valid && aggregateRepositoryWarned.compareAndSet(false, true)) {
LOG.warn("AggregationStrategy should return the oldExchange instance instead of the newExchange whenever possible" + " as otherwise this can lead to unexpected behavior with some RecoverableAggregationRepository implementations");
}
}
// update the aggregated size
answer.setProperty(Exchange.AGGREGATED_SIZE, size);
// maybe we should check completion after the aggregation
if (!preCompletion && !isEagerCheckCompletion()) {
complete = isCompleted(key, answer);
// make sure to track timeouts if not complete
if (complete == null) {
trackTimeout(key, newExchange);
}
}
if (complete == null) {
// only need to update aggregation repository if we are not complete
doAggregationRepositoryAdd(newExchange.getContext(), key, originalExchange, answer);
} else {
// if we are complete then add the answer to the list
doAggregationComplete(complete, list, key, originalExchange, answer);
}
LOG.trace("onAggregation +++ end +++ with correlation key: {}", key);
return list;
}
Aggregations