public void addExceptionPolicy(RouteContext routeContext, OnExceptionDefinition exceptionType) { if (routeContext != null) { // add error handler as child service so they get lifecycle handled Processor errorHandler = exceptionType.getErrorHandler(routeContext.getRoute().getId()); if (errorHandler != null) { addChildService(errorHandler); } } List<Class<? extends Throwable>> list = exceptionType.getExceptionClasses(); for (Class<? extends Throwable> clazz : list) { String routeId = null; // only get the route id, if the exception type is route scoped if (exceptionType.isRouteScoped()) { RouteDefinition route = ProcessorDefinitionHelper.getRoute(exceptionType); if (route != null) { routeId = route.getId(); } } ExceptionPolicyKey key = new ExceptionPolicyKey(routeId, clazz, exceptionType.getOnWhen()); exceptionPolicies.put(key, exceptionType); } }
/** * Gather all other kind of route scoped services from the given route, except error handler */ private void doGetRouteScopedServices(List<Service> services, Route route) { for (ProcessorDefinition<?> output : route.getRouteContext().getRoute().getOutputs()) { if (output instanceof OnExceptionDefinition) { OnExceptionDefinition onExceptionDefinition = (OnExceptionDefinition) output; if (onExceptionDefinition.isRouteScoped()) { Processor errorHandler = onExceptionDefinition.getErrorHandler(route.getId()); if (errorHandler != null && errorHandler instanceof Service) { services.add((Service) errorHandler); } } } else if (output instanceof OnCompletionDefinition) { OnCompletionDefinition onCompletionDefinition = (OnCompletionDefinition) output; if (onCompletionDefinition.isRouteScoped()) { Processor onCompletionProcessor = onCompletionDefinition.getOnCompletion(route.getId()); if (onCompletionProcessor != null && onCompletionProcessor instanceof Service) { services.add((Service) onCompletionProcessor); } } } } }
public void configure(RouteContext routeContext, ErrorHandler handler) { if (handler instanceof ErrorHandlerSupport) { ErrorHandlerSupport handlerSupport = (ErrorHandlerSupport) handler; List<OnExceptionDefinition> list = onExceptions.get(routeContext); if (list != null) { for (OnExceptionDefinition exception : list) { handlerSupport.addExceptionPolicy(routeContext, exception); } } } if (handler instanceof RedeliveryErrorHandler) { boolean original = ((RedeliveryErrorHandler) handler).isUseOriginalMessagePolicy(); if (original) { // ensure allow original is turned on routeContext.setAllowUseOriginalMessage(true); } } }
private static void defineGeneralExceptionDefinition(OnExceptionDefinition exceptionDefinition, int redeliveryAttempts, long redeliveryDelay, String errorQueue, boolean logRetryAttempted) { exceptionDefinition.maximumRedeliveries(redeliveryAttempts); exceptionDefinition.redeliveryDelay(redeliveryDelay); exceptionDefinition.handled(true); exceptionDefinition .retryAttemptedLogLevel(LoggingLevel.ERROR) .logRetryAttempted(logRetryAttempted) .maximumRedeliveryDelay(60000) .backOffMultiplier(10) .to(ERROR_LOG) .to(errorQueue); }
private boolean isContextScoped() { if (definition instanceof OnExceptionDefinition) { return !((OnExceptionDefinition) definition).isRouteScoped(); } else if (definition instanceof OnCompletionDefinition) { return !((OnCompletionDefinition) definition).isRouteScoped(); } return false; }
/** * Attempts to find the best suited {@link OnExceptionDefinition} to be used for handling the given thrown exception. * * @param exchange the exchange * @param exception the exception that was thrown * @return the best exception type to handle this exception, <tt>null</tt> if none found. */ protected OnExceptionDefinition getExceptionPolicy(Exchange exchange, Throwable exception) { if (exceptionPolicy == null) { throw new IllegalStateException("The exception policy has not been set"); } return exceptionPolicy.getExceptionPolicy(exceptionPolicies, exchange, exception); }
public OnExceptionDefinition getExceptionPolicy(Map<ExceptionPolicyKey, OnExceptionDefinition> exceptionPolicies, Exchange exchange, Throwable exception) { Map<Integer, OnExceptionDefinition> candidates = new TreeMap<Integer, OnExceptionDefinition>(); Map<ExceptionPolicyKey, OnExceptionDefinition> routeScoped = new LinkedHashMap<ExceptionPolicyKey, OnExceptionDefinition>(); Map<ExceptionPolicyKey, OnExceptionDefinition> contextScoped = new LinkedHashMap<ExceptionPolicyKey, OnExceptionDefinition>(); // split policies into route and context scoped initRouteAndContextScopedExceptionPolicies(exceptionPolicies, routeScoped, contextScoped); // at first check route scoped as we prefer them over context scoped // recursive up the tree using the iterator boolean exactMatch = false; Iterator<Throwable> it = createExceptionIterator(exception); while (!exactMatch && it.hasNext()) { // we should stop looking if we have found an exact match exactMatch = findMatchedExceptionPolicy(routeScoped, exchange, it.next(), candidates); } // fallback to check context scoped (only do this if there was no exact match) it = createExceptionIterator(exception); while (!exactMatch && it.hasNext()) { // we should stop looking if we have found an exact match exactMatch = findMatchedExceptionPolicy(contextScoped, exchange, it.next(), candidates); } // now go through the candidates and find the best LOG.trace("Found {} candidates", candidates.size()); if (candidates.isEmpty()) { // no type found return null; } else { // return the first in the map as its sorted and we checked route scoped first, which we prefer return candidates.values().iterator().next(); } }
private void initRouteAndContextScopedExceptionPolicies(Map<ExceptionPolicyKey, OnExceptionDefinition> exceptionPolicies, Map<ExceptionPolicyKey, OnExceptionDefinition> routeScoped, Map<ExceptionPolicyKey, OnExceptionDefinition> contextScoped) { // loop through all the entries and split into route and context scoped Set<Map.Entry<ExceptionPolicyKey, OnExceptionDefinition>> entries = exceptionPolicies.entrySet(); for (Map.Entry<ExceptionPolicyKey, OnExceptionDefinition> entry : entries) { if (entry.getKey().getRouteId() != null) { routeScoped.put(entry.getKey(), entry.getValue()); } else { contextScoped.put(entry.getKey(), entry.getValue()); } } }
/** * Determines if redelivery is enabled by checking if any of the redelivery policy * settings may allow redeliveries. * * @return <tt>true</tt> if redelivery is possible, <tt>false</tt> otherwise * @throws Exception can be thrown */ private boolean determineIfRedeliveryIsEnabled() throws Exception { // determine if redeliver is enabled either on error handler if (getRedeliveryPolicy().getMaximumRedeliveries() != 0) { // must check for != 0 as (-1 means redeliver forever) return true; } if (retryWhilePolicy != null) { return true; } // or on the exception policies if (!exceptionPolicies.isEmpty()) { // walk them to see if any of them have a maximum redeliveries > 0 or retry until set for (OnExceptionDefinition def : exceptionPolicies.values()) { String ref = def.getRedeliveryPolicyRef(); if (ref != null) { // lookup in registry if ref provided RedeliveryPolicy policy = CamelContextHelper.mandatoryLookup(camelContext, ref, RedeliveryPolicy.class); if (policy.getMaximumRedeliveries() != 0) { // must check for != 0 as (-1 means redeliver forever) return true; } } else if (def.getRedeliveryPolicy() != null) { Integer max = CamelContextHelper.parseInteger(camelContext, def.getRedeliveryPolicy().getMaximumRedeliveries()); if (max != null && max != 0) { // must check for != 0 as (-1 means redeliver forever) return true; } } if (def.getRetryWhilePolicy() != null || def.getRetryWhile() != null) { return true; } } } return false; }
/** * Should the given processor be registered. */ protected boolean registerProcessor(ProcessorDefinition<?> processor) { // skip on exception if (processor instanceof OnExceptionDefinition) { return false; } // skip on completion if (processor instanceof OnCompletionDefinition) { return false; } // skip intercept if (processor instanceof InterceptDefinition) { return false; } // skip aop if (processor instanceof AOPDefinition) { return false; } // skip policy if (processor instanceof PolicyDefinition) { return false; } // only if custom id assigned boolean only = getManagementStrategy().getManagementAgent().getOnlyRegisterProcessorWithCustomId() != null && getManagementStrategy().getManagementAgent().getOnlyRegisterProcessorWithCustomId(); if (only) { return processor.hasCustomIdAssigned(); } // use customer filter return getManagementStrategy().manageProcessor(processor); }
/** * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a> * for catching certain exceptions and handling them. * * @param exception exception to catch * @return the builder */ public OnExceptionDefinition onException(Class<? extends Throwable> exception) { // is only allowed at the top currently if (!getRouteCollection().getRoutes().isEmpty()) { throw new IllegalArgumentException("onException must be defined before any routes in the RouteBuilder"); } getRouteCollection().setCamelContext(getContext()); return getRouteCollection().onException(exception); }
/** * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a> * for catching certain exceptions and handling them. * * @param exceptions list of exceptions to catch * @return the builder */ public OnExceptionDefinition onException(Class<? extends Throwable>... exceptions) { OnExceptionDefinition last = null; for (Class<? extends Throwable> ex : exceptions) { last = last == null ? onException(ex) : last.onException(ex); } return last != null ? last : onException(Exception.class); }
public void addErrorHandlers(RouteContext routeContext, OnExceptionDefinition exception) { // only add if we not already have it List<OnExceptionDefinition> list = onExceptions.get(routeContext); if (list == null) { list = new ArrayList<OnExceptionDefinition>(); onExceptions.put(routeContext, list); } if (!list.contains(exception)) { list.add(exception); } }
protected void cloneBuilder(ErrorHandlerBuilderSupport other) { if (!onExceptions.isEmpty()) { Map<RouteContext, List<OnExceptionDefinition>> copy = new HashMap<RouteContext, List<OnExceptionDefinition>>(onExceptions); other.onExceptions = copy; } other.exceptionPolicyStrategy = exceptionPolicyStrategy; }
@Override public void addErrorHandlers(RouteContext routeContext, OnExceptionDefinition exception) { ErrorHandlerBuilder handler = handlers.get(routeContext); if (handler != null) { handler.addErrorHandlers(routeContext, exception); } super.addErrorHandlers(routeContext, exception); }
private ErrorHandlerBuilder createErrorHandler(RouteContext routeContext) { ErrorHandlerBuilder handler = (ErrorHandlerBuilder)lookupErrorHandlerBuilder(routeContext, getRef()); ObjectHelper.notNull(handler, "error handler '" + ref + "'"); // configure if the handler support transacted supportTransacted = handler.supportTransacted(); List<OnExceptionDefinition> list = getErrorHandlers(routeContext); if (list != null) { for (OnExceptionDefinition exceptionType : list) { handler.addErrorHandlers(routeContext, exceptionType); } } return handler; }
public OnExceptionDefinition getExceptionPolicy(Map<ExceptionPolicyKey, OnExceptionDefinition> exceptionPolicices, Exchange exchange, Throwable exception) { // This is just an example that always forces the exception type configured // with MyPolicyException to win. return exceptionPolicices.get(new ExceptionPolicyKey(null, MyPolicyException.class, null)); }
private void setupPolicies() { strategy = new DefaultExceptionPolicyStrategy(); policies = new HashMap<ExceptionPolicyKey, OnExceptionDefinition>(); type1 = new OnExceptionDefinition(CamelExchangeException.class); type2 = new OnExceptionDefinition(Exception.class); type3 = new OnExceptionDefinition(IOException.class); policies.put(new ExceptionPolicyKey(null, CamelExchangeException.class, null), type1); policies.put(new ExceptionPolicyKey(null, Exception.class, null), type2); policies.put(new ExceptionPolicyKey(null, IOException.class, null), type3); }
private void setupPoliciesNoTopLevelException() { // without the top level exception that can be used as fallback strategy = new DefaultExceptionPolicyStrategy(); policies = new HashMap<ExceptionPolicyKey, OnExceptionDefinition>(); type1 = new OnExceptionDefinition(CamelExchangeException.class); type3 = new OnExceptionDefinition(IOException.class); policies.put(new ExceptionPolicyKey(null, CamelExchangeException.class, null), type1); policies.put(new ExceptionPolicyKey(null, IOException.class, null), type3); }
private void setupPoliciesCausedBy() { strategy = new DefaultExceptionPolicyStrategy(); policies = new HashMap<ExceptionPolicyKey, OnExceptionDefinition>(); type1 = new OnExceptionDefinition(FileNotFoundException.class); type2 = new OnExceptionDefinition(ConnectException.class); type3 = new OnExceptionDefinition(IOException.class); policies.put(new ExceptionPolicyKey(null, FileNotFoundException.class, null), type1); policies.put(new ExceptionPolicyKey(null, IOException.class, null), type2); policies.put(new ExceptionPolicyKey(null, ConnectException.class, null), type3); }
public void testClosetMatch3() { setupPolicies(); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, new ConnectException("")); assertEquals(type3, result); result = strategy.getExceptionPolicy(policies, null, new SocketException("")); assertEquals(type3, result); result = strategy.getExceptionPolicy(policies, null, new FileNotFoundException()); assertEquals(type3, result); }
public void testClosetMatch2() { setupPolicies(); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, new ClassCastException("")); assertEquals(type2, result); result = strategy.getExceptionPolicy(policies, null, new NumberFormatException("")); assertEquals(type2, result); result = strategy.getExceptionPolicy(policies, null, new NullPointerException()); assertEquals(type2, result); }
public void testClosetMatch1() { setupPolicies(); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, new ValidationException(null, "")); assertEquals(type1, result); result = strategy.getExceptionPolicy(policies, null, new ExchangeTimedOutException(null, 0)); assertEquals(type1, result); }
public void testCausedBy() { setupPoliciesCausedBy(); IOException ioe = new IOException("Damm"); ioe.initCause(new FileNotFoundException("Somefile not found")); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, ioe); assertEquals(type1, result); }
public void testCausedByWrapped() { setupPoliciesCausedBy(); IOException ioe = new IOException("Damm"); ioe.initCause(new FileNotFoundException("Somefile not found")); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, new RuntimeCamelException(ioe)); assertEquals(type1, result); }
public void testCausedByNotConnected() { setupPoliciesCausedBy(); IOException ioe = new IOException("Damm"); ioe.initCause(new ConnectException("Not connected")); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, ioe); assertEquals(type3, result); }
public void testCausedByOtherIO() { setupPoliciesCausedBy(); IOException ioe = new IOException("Damm"); ioe.initCause(new MalformedURLException("Bad url")); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, ioe); assertEquals(type2, result); }
public void testOnePolicyChildFirst() { List<Class<? extends Throwable>> exceptions = new ArrayList<Class<? extends Throwable>>(); exceptions.add(ChildException.class); exceptions.add(ParentException.class); ErrorHandlerSupport support = new ShuntErrorHandlerSupport(); support.addExceptionPolicy(null, new OnExceptionDefinition(exceptions)); assertEquals(ChildException.class, getExceptionPolicyFor(support, new ChildException(), 0)); assertEquals(ParentException.class, getExceptionPolicyFor(support, new ParentException(), 1)); }
public void testOnePolicyChildLast() { List<Class<? extends Throwable>> exceptions = new ArrayList<Class<? extends Throwable>>(); exceptions.add(ParentException.class); exceptions.add(ChildException.class); ErrorHandlerSupport support = new ShuntErrorHandlerSupport(); support.addExceptionPolicy(null, new OnExceptionDefinition(exceptions)); assertEquals(ChildException.class, getExceptionPolicyFor(support, new ChildException(), 1)); assertEquals(ParentException.class, getExceptionPolicyFor(support, new ParentException(), 0)); }
public void testTwoPolicyChildFirst() { ErrorHandlerSupport support = new ShuntErrorHandlerSupport(); support.addExceptionPolicy(null, new OnExceptionDefinition(ChildException.class)); support.addExceptionPolicy(null, new OnExceptionDefinition(ParentException.class)); assertEquals(ChildException.class, getExceptionPolicyFor(support, new ChildException(), 0)); assertEquals(ParentException.class, getExceptionPolicyFor(support, new ParentException(), 0)); }
public void testTwoPolicyChildLast() { ErrorHandlerSupport support = new ShuntErrorHandlerSupport(); support.addExceptionPolicy(null, new OnExceptionDefinition(ParentException.class)); support.addExceptionPolicy(null, new OnExceptionDefinition(ChildException.class)); assertEquals(ChildException.class, getExceptionPolicyFor(support, new ChildException(), 0)); assertEquals(ParentException.class, getExceptionPolicyFor(support, new ParentException(), 0)); }
protected void defineExceptionHandlers() { OnExceptionDefinition exceptionDefinition = this.onException(Exception.class); if (this.redeliveryAttempts != 0) { exceptionDefinition.maximumRedeliveries(this.redeliveryAttempts); } else exceptionDefinition.maximumRedeliveries(-1); if (this.redeliveryDelay != 0L) { exceptionDefinition.redeliveryDelay(this.redeliveryDelay); } else exceptionDefinition.redeliveryDelay(1000L); exceptionDefinition .retryAttemptedLogLevel(LoggingLevel.ERROR) .logRetryStackTrace(true) .logRetryAttempted(true) .maximumRedeliveryDelay(60000) .backOffMultiplier(2) .to(AbstractRouteBuilder.ERROR_LOG) .to(this.errorQueue); }
protected void handleException(Exchange exchange, RedeliveryData data, boolean isDeadLetterChannel) { Exception e = exchange.getException(); // store the original caused exception in a property, so we can restore it later exchange.setProperty(Exchange.EXCEPTION_CAUGHT, e); // find the error handler to use (if any) OnExceptionDefinition exceptionPolicy = getExceptionPolicy(exchange, e); if (exceptionPolicy != null) { data.currentRedeliveryPolicy = exceptionPolicy.createRedeliveryPolicy(exchange.getContext(), data.currentRedeliveryPolicy); data.handledPredicate = exceptionPolicy.getHandledPolicy(); data.continuedPredicate = exceptionPolicy.getContinuedPolicy(); data.retryWhilePredicate = exceptionPolicy.getRetryWhilePolicy(); data.useOriginalInMessage = exceptionPolicy.getUseOriginalMessagePolicy() != null && exceptionPolicy.getUseOriginalMessagePolicy(); // route specific failure handler? Processor processor = null; UnitOfWork uow = exchange.getUnitOfWork(); if (uow != null && uow.getRouteContext() != null) { String routeId = uow.getRouteContext().getRoute().getId(); processor = exceptionPolicy.getErrorHandler(routeId); } else if (!exceptionPolicy.getErrorHandlers().isEmpty()) { // note this should really not happen, but we have this code as a fail safe // to be backwards compatible with the old behavior log.warn("Cannot determine current route from Exchange with id: {}, will fallback and use first error handler.", exchange.getExchangeId()); processor = exceptionPolicy.getErrorHandlers().iterator().next(); } if (processor != null) { data.failureProcessor = processor; } // route specific on redelivery? processor = exceptionPolicy.getOnRedelivery(); if (processor != null) { data.onRedeliveryProcessor = processor; } // route specific on exception occurred? processor = exceptionPolicy.getOnExceptionOccurred(); if (processor != null) { data.onExceptionProcessor = processor; } } // only log if not failure handled or not an exhausted unit of work if (!ExchangeHelper.isFailureHandled(exchange) && !ExchangeHelper.isUnitOfWorkExhausted(exchange)) { String msg = "Failed delivery for " + ExchangeHelper.logIds(exchange) + ". On delivery attempt: " + data.redeliveryCounter + " caught: " + e; logFailedDelivery(true, false, false, false, isDeadLetterChannel, exchange, msg, data, e); } data.redeliveryCounter = incrementRedeliveryCounter(exchange, e, data); }
public List<OnExceptionDefinition> getErrorHandlers(RouteContext routeContext) { return onExceptions.get(routeContext); }
public void setErrorHandlers(RouteContext routeContext, List<OnExceptionDefinition> exceptions) { this.onExceptions.put(routeContext, exceptions); }
public void testDirectMatch1() { setupPolicies(); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, new CamelExchangeException("", null)); assertEquals(type1, result); }
public void testDirectMatch2() { setupPolicies(); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, new Exception("")); assertEquals(type2, result); }
public void testDirectMatch3() { setupPolicies(); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, new IOException("")); assertEquals(type3, result); }
public void testNoMatch1ThenMatchingJustException() { setupPolicies(); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, new AlreadyStoppedException()); assertEquals(type2, result); }
public void testNoMatch1ThenNull() { setupPoliciesNoTopLevelException(); OnExceptionDefinition result = strategy.getExceptionPolicy(policies, null, new AlreadyStoppedException()); assertNull("Should not find an exception policy to use", result); }