/** * Populate the {@link MethodInvokingRouter} for the method * of the provided service and its method with provided options from {@link RouterSpec}. * @param service the service to use. * @param methodName the method to invoke. * @param routerConfigurer the {@link Consumer} to provide {@link MethodInvokingRouter} options. * @return the current {@link IntegrationFlowDefinition}. * @see MethodInvokingRouter */ public B route(Object service, String methodName, Consumer<RouterSpec<Object, MethodInvokingRouter>> routerConfigurer) { MethodInvokingRouter router; if (StringUtils.hasText(methodName)) { router = new MethodInvokingRouter(service, methodName); } else { router = new MethodInvokingRouter(service); } return route(new RouterSpec<>(router), routerConfigurer); }
/** * Cannot be invoked if {@link #subFlowMapping(Object, IntegrationFlow)} is used. * @param suffix the suffix to set. * @return the router spec. * @see AbstractMappingMessageRouter#setSuffix(String) */ public RouterSpec<K, R> suffix(String suffix) { Assert.state(this.componentsToRegister.isEmpty(), "The 'prefix'('suffix') and 'subFlowMapping' are mutually exclusive"); this.suffix = suffix; this.handler.setSuffix(suffix); return _this(); }
@Bean public IntegrationFlow routeFlow() { return IntegrationFlows.from("routerInput") .<Integer, Boolean>route(p -> p % 2 == 0, m -> m.channelMapping(true, "evenChannel") .subFlowMapping(false, f -> f.<Integer>handle((p, h) -> p * 3)) .defaultOutputToParentFlow()) .channel(MessageChannels.queue("oddChannel")) .get(); }
/** * Add a subflow as an alternative to a {@link #channelMapping(Object, String)}. * {@link #prefix(String)} and {@link #suffix(String)} cannot be used when subflow * mappings are used. * <p> If subflow should refer to the external {@link IntegrationFlow} bean and * there is a requirement to expect reply from there, such a reference should be * wrapped with a {@code .gateway()}: * <pre class="code"> * {@code * .subFlowMapping(false, sf -> sf.gateway(evenFlow()))) * } * </pre> * @param key the key. * @param subFlow the subFlow. * @return the router spec. */ public RouterSpec<K, R> subFlowMapping(K key, IntegrationFlow subFlow) { Assert.notNull(key, "'key' must not be null"); Assert.state(!(StringUtils.hasText(this.prefix) || StringUtils.hasText(this.suffix)), "The 'prefix'('suffix') and 'subFlowMapping' are mutually exclusive"); MessageChannel channel = obtainInputChannelFromFlow(subFlow, false); Assert.isInstanceOf(NamedComponent.class, channel, () -> "The routing channel '" + channel + "' from the flow '" + subFlow + "' must be instance of 'NamedComponent'."); this.mappingProvider.addMapping(key, (NamedComponent) channel); return _this(); }
@Bean public IntegrationFlow exceptionTypeRouteFlow() { return f -> f .routeByException(r -> r .channelMapping(IllegalArgumentException.class, "illegalArgumentChannel") .channelMapping(RuntimeException.class, "runtimeExceptionChannel") .subFlowMapping(MessageHandlingException.class, sf -> sf.channel("messageHandlingExceptionChannel")) .defaultOutputChannel("exceptionRouterDefaultChannel")); }
@Bean public IntegrationFlow routerAsNonLastFlow() { return f -> f .<String, String>route(p -> p, r -> r.resolutionRequired(false) .defaultOutputToParentFlow()) .channel(MessageChannels.queue("routerAsNonLastDefaultOutputChannel")); }
@Bean public IntegrationFlow routeSubflowWithoutReplyToMainFlow() { return f -> f .<String, Boolean>route("BOO"::equals, m -> m .resolutionRequired(false) .subFlowMapping(true, sf -> sf .transform(String.class, String::toLowerCase) .channel(MessageChannels.queue("routerSubflowResult"))) .defaultSubFlowMapping(sf -> sf.channel("defaultOutputChannel"))); }
@Bean public IntegrationFlow routeSubflowToReplyChannelFlow() { return f -> f .<Boolean>route("true", m -> m .subFlowMapping(true, upperCase()) ); }
@Bean public IntegrationFlow payloadTypeRouteFlow() { return f -> f .<Object, Class<?>>route(Object::getClass, m -> m .channelMapping(String.class, "stringsChannel") .channelMapping(Integer.class, "integersChannel")); }
@Bean public IntegrationFlow routeMultiMethodInvocationFlow() { return IntegrationFlows.from("routerMultiInput") .route(String.class, p -> p.equals("foo") || p.equals("bar") ? new String[] { "foo", "bar" } : null, s -> s.suffix("-channel")) .get(); }
@Bean public IntegrationFlow routeSubflowWithoutReplyToMainFlow() { return f -> f .<String, Boolean>route("BOO"::equals, m -> m .resolutionRequired(false) .subFlowMapping(true, sf -> sf .transform(String.class, String::toLowerCase) .channel(c -> c.queue("routerSubflowResult"))) .defaultSubFlowMapping(sf -> sf.channel("defaultOutputChannel"))); }
/** * Add a subflow as an alternative to a {@link #channelMapping(Object, String)}. * {@link #prefix(String)} and {@link #suffix(String)} cannot be used when subflow * mappings are used. * <p> If subflow should refer to the external {@link IntegrationFlow} bean and * there is a requirement to expect reply from there, such a reference should be * wrapped with a {@code .gateway()}: * <pre class="code"> * {@code * .subFlowMapping(false, sf -> sf.gateway(evenFlow()))) * } * </pre> * @param key the key. * @param subFlow the subFlow. * @return the router spec. */ public RouterSpec<K, R> subFlowMapping(K key, IntegrationFlow subFlow) { Assert.notNull(key, "'key' must not be null"); Assert.state(!(StringUtils.hasText(this.prefix) || StringUtils.hasText(this.suffix)), "The 'prefix'('suffix') and 'subFlowMapping' are mutually exclusive"); MessageChannel channel = obtainInputChannelFromFlow(subFlow, false); Assert.isInstanceOf(NamedComponent.class, channel, () -> "The routing channel '" + channel + "' from the flow '" + subFlow + "' must be instance of 'NamedComponent'."); this.mappingProvider.addMapping(key, (NamedComponent) channel); return _this(); }
@Bean public IntegrationFlow routerTwoSubFlows() { return f -> f .split() .<Integer, Boolean>route(p -> p % 2 == 0, m -> m .subFlowMapping(true, sf -> sf.<Integer>handle((p, h) -> p * 2)) .subFlowMapping(false, sf -> sf.<Integer>handle((p, h) -> p * 3))) .aggregate() .channel(MessageChannels.queue("routerTwoSubFlowsOutput")); }
@Bean public IntegrationFlow routerAsNonLastFlow() { return f -> f .<String, String>route(p -> p, r -> r.resolutionRequired(false) .defaultOutputToParentFlow()) .channel(MessageChannels.queue("routerAsNonLastDefaultOutputChannel")); }
@Bean public IntegrationFlow myFlow() throws IOException { return IntegrationFlows.from(feedMessageSource()) //4 .<SyndEntry, String> route(payload -> payload.getCategories().get(0).getName(),//5 mapping -> mapping.channelMapping("releases", "releasesChannel") //6 .channelMapping("engineering", "engineeringChannel") .channelMapping("news", "newsChannel")) .get(); // 7 }
@Bean public IntegrationFlow routeMultiMethodInvocationFlow() { return IntegrationFlows.from("routerMultiInput") .route(String.class, p -> p.equals("foo") || p.equals("bar") ? new String[] {"foo", "bar"} : null, s -> s.suffix("-channel")) .get(); }
/** * @param resolutionRequired the resolutionRequired. * @return the router spec. * @see AbstractMappingMessageRouter#setResolutionRequired(boolean) */ public RouterSpec<K, R> resolutionRequired(boolean resolutionRequired) { this.handler.setResolutionRequired(resolutionRequired); return _this(); }
/** * Populate the {@link ExpressionEvaluatingRouter} for provided SpEL expression * with provided options from {@link RouterSpec}. * @param expression the expression to use. * @param routerConfigurer the {@link Consumer} to provide {@link ExpressionEvaluatingRouter} options. * @param <T> the target result type. * @return the current {@link IntegrationFlowDefinition}. */ public <T> B route(String expression, Consumer<RouterSpec<T, ExpressionEvaluatingRouter>> routerConfigurer) { return route(new RouterSpec<>(new ExpressionEvaluatingRouter(PARSER.parseExpression(expression))), routerConfigurer); }
@Bean public IntegrationFlow routeFlow() { return IntegrationFlows.from("routerInput") .<Integer, Boolean>route(p -> p % 2 == 0, m -> m.channelMapping(true, "evenChannel") .subFlowMapping(false, f -> f.<Integer>handle((p, h) -> p * 3)) .defaultOutputToParentFlow()) .channel(c -> c.queue("oddChannel")) .get(); }
private RouterSpec<Boolean, MethodInvokingRouter> routeProducts(RouterSpec<Boolean, MethodInvokingRouter> mapping) { return mapping .subFlowMapping(true, sf -> sf.handle(productProcessor(), "fastProcess")) .subFlowMapping(false, sf -> sf.handle(productProcessor(), "process")); }