How to configure Redis inbound channel adaptor in Spring integration DSL? - spring

I am trying to set up a caching service using Spring boot/integration. This service has to retrieve data from Redis database every 6 minutes. I have followed this documentation and there is no example for Spring integration DSL.
<int-redis:inbound-channel-adapter id="redisAdapter"
topics="thing1, thing2"
channel="receiveChannel"
error-channel="testErrorChannel"
message-converter="testConverter" />
I have also followed the example mentioned in this StackOverflow page.
#Bean
RedisQueueMessageDrivenEndpoint redisQueueMessageDrivenEndpoint(RedisConnectionFactory redisConnectionFactory, RedisSerializer<?> serializer) {
RedisQueueMessageDrivenEndpoint endpoint =
new RedisQueueMessageDrivenEndpoint("archive.post.publication.queue", redisConnectionFactory);
endpoint.setOutputChannelName("postPublicationChannel");
endpoint.setErrorChannelName("postPublicationLoggingChannel");
endpoint.setReceiveTimeout(5000);
endpoint.setSerializer(serializer);
return endpoint;
}
I have tried examples from various documentation and none of them related to my scenario. Any help is much appreciated?

Related

Is it a good idea to handle optional JWT Authentication in Filter?

I am new to Spring Boot and my current project is a REST API developed in Spring Webflux. The goal is to have an endpoint which has an optional JWT Token, allowing you ti create things anonymously or not. But all the starter guides to Spring Security are really complicated and use Spring MVC, as far as I can tell.
Now my idea was to create a HandlerFilterFunction looking like
class AuthenticationFilter : HandlerFilterFunction<ServerResponse, ServerResponse> {
override fun filter(request: ServerRequest, next: HandlerFunction<ServerResponse>): Mono<ServerResponse> {
val authHeader = request.headers().header("Authorization").firstOrNull()
// get user from database
request.attributes()["user"] = user
return next.handle(request)
}
}
and adding it to the router {...} bean.
Is this a good idea, or should I go another router? If so, can somebody point me towards a JWT tutorial for Spring Webflux.
The Spring Security docs point to a JWT-Based WebFlux Resource Server sample in the codebase.
It's not Kotlin-based, so I also posted a sample of my own just now; hopefully, it helps get you started.
As for your question, yes, you can create a filter of your own, though Spring Security ships with a BearerTokenAuthenticationFilter that already does what your filter would likely do. The first linked sample adds this filter manually while the second sample lets Spring Boot add it.

Use Spring Integration DSL to read from Tibco EMS topic

I've been trying to configure spring integration dsl to read from a Tibco EMS topic , do some processing on the received message and then push it to an ActiveMQ queue. I was able to set this up successfully using XML configuration, but wanted to use spring integration dsl instead. I couldn't figure out, neither could find any help online about it.
My configuration for pushing message to ActiveMQ is something like this -
#Bean
public IntegrationFlow toActiveMQFlow(
MessageChannel channel,
ActiveMQQueue queue,
CachingConnectionFactory cachingConnectionFactory) {
return IntegrationFlows.from(channel)
.transform(Object::toString)
.handle(Jms.outboundAdapter(cachingConnectionFactory).destination(queue))
.get();
}
And I'm thinking that the configuration for reading from Tibco EMS topics should be something like this -
#Bean
public IntegrationFlow fromTibcoTopicFlow(
MessageChannel channel,
ConnectionFactory tibcoEmsConnectionFactory,
Topic tibcoTopic
) {
return IntegrationFlows
.from(SomeInboundAdapter(tibcoEmsConnectionFactory).destination(tibcoTopic))
.transform(Object::toString)
.channel(channel)
.get();
}
Since I did not find much help on the latter configuration, is resorting to the XML configuration my only option here?
Kindly correct/edit/point out any mistakes I've made, still learning Spring Integration DSL.
Appreciate your help!
You need to use a Jms.messageDrivenChannelAdapter(ConnectionFactory connectionFactory).
And souldn't use a spring-integration-java-dsl. It was merged to the core project since version 5.0: https://docs.spring.io/spring-integration/docs/5.0.9.RELEASE/reference/html/whats-new.html#_java_dsl
We have fixed the issue with an old Java DSL jar on classpath: https://jira.spring.io/browse/INT-4551

How to use ActiveMQ queue with Spring Integration

I have a local ActiveMQ server and i want to poll messages from a queue named "test" using Spring Integration.
After i have polled the message i want to send it to another channel which would write it on a text file in the file system.
I have seen some examples using
<int-jms:message-driven-channel-adapter id="jmsIn" destination="inQueue" channel="exampleChannel"/>
I want to create this JMS "poller" using Java Annotations. I could not find any reference on how to replace the above XML stuff to annotations.
Could anyone provide a working snippet that would have connection factory configuration and jms:message-driven-channel-adapter done with annotations?
P.S. Here is a reference that has XML configuration
https://examples.javacodegeeks.com/enterprise-java/spring/integration/spring-boot-integration-activemq-example/
Thanks a lot in advance !
Well, for proper Java & Annotations configuration you need to consider to use Spring Integration Java DSL.
Here is some example for the <int-jms:message-driven-channel-adapter> equivalent:
#Bean
public IntegrationFlow jmsMessageDrivenRedeliveryFlow() {
return IntegrationFlows
.from(Jms.messageDrivenChannelAdapter(jmsConnectionFactory())
.errorChannel(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
.destination("jmsMessageDrivenRedelivery")
.configureListenerContainer(c -> c
.transactionManager(mock(PlatformTransactionManager.class))
.id("jmsMessageDrivenRedeliveryFlowContainer")))
.<String, String>transform(p -> {
throw new RuntimeException("intentional");
})
.get();
}
To write to file you need to use a Files.outboundAdapter(): https://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/files.html#_configuring_with_the_java_dsl_9
I agree that we are missing similar Docs for JMS part, so feel free to raise a JIRA on the matter.

Spring Boot 2 integrate Brave MySQL-Integration into Zipkin

I am trying to integrate the Brave MySql Instrumentation into my Spring Boot 2.x service to automatically let its interceptor enrich my traces with spans concerning MySql-Queries.
The current Gradle-Dependencies are the following
compile 'io.zipkin.zipkin2:zipkin:2.4.5'
compile('io.zipkin.reporter2:zipkin-sender-okhttp3:2.3.1')
compile('io.zipkin.brave:brave-instrumentation-mysql:4.14.3')
compile('org.springframework.cloud:spring-cloud-starter-zipkin:2.0.0.M5')
I already configured Sleuth successfully to send traces concerning HTTP-Request to my Zipkin-Server and now I wanted to add some spans for each MySql-Query the service does.
The TracingConfiguration it this:
#Configuration
public class TracingConfiguration {
/** Configuration for how to send spans to Zipkin */
#Bean
Sender sender() {
return OkHttpSender.create("https://myzipkinserver.com/api/v2/spans");
}
/** Configuration for how to buffer spans into messages for Zipkin */
#Bean AsyncReporter<Span> spanReporter() {
return AsyncReporter.create(sender());
}
#Bean Tracing tracing(Reporter<Span> spanListener) {
return Tracing.newBuilder()
.spanReporter(spanReporter())
.build();
}
}
The Query-Interceptor works properly, but my problem now is that the spans are not added to the existing trace but each are added to a new one.
I guess its because of the creation of a new sender/reporter in the configuration, but I have not been able to reuse the existing one created by the Spring Boot Autoconfiguration.
That would moreover remove the necessity to redundantly define the Zipkin-Url (because it is already defined for Zipkin in my application.yml).
I already tried autowiring the Zipkin-Reporter to my Bean, but all I got is a SpanReporter - but the Brave-Tracer-Builder requries a Reporter<Span>
Do you have any advice for me how to properly wire things up?
Please use latest snapshots. Sleuth in latest snapshots uses brave internally so integration will be extremely simple.

How to configure StepExecutionListener with Spring Integration DSL

I am trying to configure a Spring Batch listener to send a message to a Spring Integration Gateway for StepExecution events.
The following link explains how to configure this with XML
http://docs.spring.io/spring-batch/trunk/reference/html/springBatchIntegration.html#providing-feedback-with-informational-messages
How can this be setup using Spring Integration DSL? I've found no way to configure a gateway with a service interface using DSL.
At the moment I worked around this by implementing an actual StepExecutionListener, and have this then calling an interface which is annotated with #MessagingGateway (calling the corresponding #Gateway method) in order to get a message to a channel. And I then setup an Integration DSL flow for this channel.
Is there a simpler way using DSL, avoiding that workaround? Is there some way to connect a Batch listener direct to a gateway, like one can using XML config?
Cheers,
Menno
First of all SI DSL is just an extension of existing SI Java and Annotation configuration, so it can be used together with any other Java config. Of course an XML #Import is also posible.
There is no gateway configuration in the DSL, because its methods can't be wired with linear IntegrationFlow. There is need to provide downstream flows for each method.
So, #MessagingGateway is a right way to go ahead:
#MessagingGateway(name = "notificationExecutionsListener", defaultRequestChannel = "stepExecutionsChannel")
public interface MyStepExecutionListener extends StepExecutionListener {}
From other side #MessagingGateway parsing as well as <gateway> tag parsing ends up with GatewayProxyFactoryBean definition. So, you just can declare that bean, if you don't want to introduce a new class:
#Bean
public GatewayProxyFactoryBean notificationExecutionsListener(MessageChannel stepExecutionsChannel) {
GatewayProxyFactoryBean gateway = new GatewayProxyFactoryBean(StepExecutionListener.class);
gateway.setDefaultRequestChannel(stepExecutionsChannel);
return gateway;
}
After the latest Milestone 3 I have an idea to introduce nested flows, when we may be able to introduce Gateway support for flows. Something like this:
#Bean
public IntegrationFlow gatewayFlow() {
return IntegrationFlows
.from(MyGateway.class, g ->
g.method("save", f -> f.transform(...)
.filter(...))
.method("delete", f -> f.handle(...)))
.handle(...)
.get();
}
However I'm not sure that it will simplify the life, as far as any nested Lambda just adds more noise and might break loosely coupling principle.

Resources