Engineering
Releases
News and Events

Spring Integration Java DSL 1.0 Milestone 3 Available

We are pleased to announce that the Java DSL for Spring Integration 1.0 Milestone 3 has been released.
Please use the Milestone Repository with Maven or Gradle,
download a
distribution archive,
or see the project home page
for more information.

Since the last Milestone 2,
some new features and further improvements, as well as a number of bug fixes have been included to this Milestone,
with the GA release due around the end of October.

First of all thanks for all who are interested in this Spring Integration Extension, provide feedback,
share their thoughts and even contribute.

Here is a summary of major changes:

Spring Integration 4.1

Current Milestone provides compatibility with
Spring Integration 4.1
as well as with Spring Framework 4.1.

The changes include:

  • Spring Integration 4.1 provides Channel names late resolution,
    which allows for DSL IntegrationFlows definitions to be based on just channel names and avoid workarounds that required
    @DependsOn from one flow to another;

  • a number of Messaging performance improvements have been included in Spring Framework 4.1, when Spring Integration
    (as well as its DSL) is based on Spring Messaging module;

  • Spring Framework 4.1 introduced the [SpEL Compiler](http://docs.spring
    .io/spring/docs/current/spring-framework-reference/html/expressions.html#expressions-spel-compilation).
    It is very useful for Spring Integration, which extensively uses SpEL at runtime. You can enable the SpEL Compiler using the
    spring.expression.compiler.mode System Property with a value of IMMEDIATE or MIXED.

Of course, compatibility with Spring Integration 4.0 still remains.

IntegrationFlow Lambda

The IntegrationFlow bean definition can now be presented as a Lambda too, to simplify the DSL usage:

@Bean
public IntegrationFlow lambdaFlow() {
    return f -> f.filter("World"::equals)
                 .transform("Hello "::concat)
                 .handle(System.out::println);
}

Actually we just made IntegrationFlow a functional interface with a single method
define(IntegrationFlowDefinition<?> flow) and the IntegrationFlowBeanPostProcessor just converts that ‘fake’ bean
to the real StandardIntegrationFlow based on implicit IntegrationFlowBuilder. The only limitation is with such a
definition, that it is based on an implicit DirectChannel with lambdaFlow.input bean name.

Protocol-specific Adapters

With this Milestone, several new protocol-specific Namespace factories have been introduced: Files,
(S)Ftp and Mail. Some simple samples of their usage:
````java
@Autowired
private DefaultFtpSessionFactory ftpSessionFactory;

@Bean
public IntegrationFlow ftpInboundFlow() {
return IntegrationFlows
.from(Ftp.inboundAdapter(this.ftpSessionFactory)
.preserveTimestamp(true)
.remoteDirectory(“ftpSource”)
.regexFilter(“.*\.txt$”)
.localFilenameGeneratorExpression(“#this.toUpperCase() + ‘.a’”)
.localDirectory(new File(“tmp”)),
e -> e.id(“ftpInboundAdapter”))
.channel(MessageChannels.queue(“ftpInboundResultChannel”))
.get();
}

@Bean
public IntegrationFlow tailFlow() {
return IntegrationFlows
.from(Files.tailAdapter(new File(tmpDir, “TailTest”))
.delay(500)
.end(false))
.channel(MessageChannels.queue(“tailChannel”))
.get();
}

@Bean
public IntegrationFlow imapIdleFlow() throws AddressException {
return IntegrationFlows
.from(Mail.imapIdleAdapter(“imap://user:[email protected]:993/INBOX")
.searchTermStrategy((f, l) ->
new AndTerm(new FromTerm(new InternetAddress(”bar@baz")),
new FlagTerm(new Flags(Flags.Flag.SEEN), false)))
.javaMailProperties(p -> p
.put(“mail.debug”, “true”)
.put(“mail.imap.connectionpoolsize”, “5”))
.shouldReconnectAutomatically(true))
.enrichHeaders(s -> s.headerExpressions(h -> h
.put(MailHeaders.SUBJECT, “payload.subject”)
.put(MailHeaders.FROM, “payload.from[0].toString()”)))
.channel(MessageChannels.queue(“imapIdleChannel”))
.get();
}
````

Support additions

As you could notice in the last IMAP sample the .javaMailProperties() and .enrichHeaders() have fluent syntax
to specify Properties and Map<String, String> as inline objects. Unfortunately, Java doesn’t provide a Builder API
for those simple classes, hence we do that for you and provide functional interfaces to build Properties and Map
from Lambdas. For example, the Mail.headers() provides a MailHeadersBuilder - an extension of MapBuilder,
which can be used in the .enrichHeaders() as well:
java @Bean public IntegrationFlow sendMailFlow() { return f -> f.enrichHeaders(Mail.headers().subject("foo").from("[email protected]").to("[email protected]")) .handle(Mail.outboundAdapter("smtp.gmail.com") .credentials("user", "pw") .protocol("smtp"))); }

Of course, this is an equivalent of <int-mail:header-enricher> from XML configuration.

Wrapping up

You can obtain more information about these and existing classes from their
source code.

We look forward to your comments and feedback (StackOverflow (spring-integration tag),
Spring JIRA, GitHub)
as soon as possible and report issues you find before we GA towards over a couple months.

SpringOne 2GX 2014

Some of those mentioned topics are being covered at SpringOne tomorrow. Please attend Gary Russell’s Session
to learn more about these and other Spring Integration improvements added in the last 12 months.

comments powered by Disqus