/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.core.routing; import static org.mule.runtime.api.i18n.I18nMessageFactory.createStaticMessage; import org.mule.runtime.api.exception.MuleException; import org.mule.runtime.core.api.Event; import org.mule.runtime.core.api.Event.Builder; import org.mule.runtime.core.api.MuleContext; import org.mule.runtime.core.api.processor.Processor; import org.mule.runtime.core.routing.filters.ExpressionFilter; import java.util.List; /** * * Routing strategy that routes the message through a list of {@link Processor} until one is successfully executed. * * The message will be route to the first route, if the route execution is successful then execution ends, if not the message will * be route to the next route. This continues until a successful route is found. */ public class FirstSuccessfulRoutingStrategy extends AbstractRoutingStrategy { protected ExpressionFilter failureExpressionFilter; private RouteProcessor processor; /** * @param muleContext * @param failureExpression Mule expression that validates if a {@link Processor} execution was successful or not. */ public FirstSuccessfulRoutingStrategy(final MuleContext muleContext, final String failureExpression, RouteProcessor processor) { super(muleContext); if (failureExpression != null) { failureExpressionFilter = new ExpressionFilter(failureExpression); } else { failureExpressionFilter = new ExpressionFilter("mel:exception != null"); } failureExpressionFilter.setMuleContext(muleContext); this.processor = processor; } @Override public Event route(Event event, List<Processor> messageProcessors) throws MuleException { Event returnEvent = null; boolean failed = true; Exception failExceptionCause = null; for (Processor mp : messageProcessors) { try { Event toProcess = cloneEventForRouting(event, mp); returnEvent = processor.processRoute(mp, toProcess); if (returnEvent == null) { failed = false; } else if (returnEvent.getMessage() == null) { failed = true; } else { Builder builder = Event.builder(returnEvent); failed = returnEvent == null || failureExpressionFilter.accept(returnEvent, builder); returnEvent = builder.build(); } } catch (Exception ex) { failed = true; failExceptionCause = ex; } if (!failed) { break; } } if (failed) { if (failExceptionCause != null) { throw new RoutingFailedException(createStaticMessage("all message processor failed during first successful routing strategy"), failExceptionCause); } else { throw new RoutingFailedException(createStaticMessage("all message processor failed during first successful routing strategy")); } } return returnEvent; } private Event cloneEventForRouting(Event event, Processor mp) throws MuleException { validateMessageIsNotConsumable(event, event.getMessage()); return createEventToRoute(event, event.getMessage(), mp); } interface RouteProcessor { Event processRoute(Processor route, Event event) throws MuleException; } }