How to use ShedLock in Spring Integration? - spring

I am combining the Spring Batch and Spring Integration, I am using the poller with a corn:
#Bean
#SchedulerLock(name = "importEntitiesRiskCodes", lockAtMostForString = "PT5M")
public IntegrationFlow integrationFlow() {
return IntegrationFlows.from(fileReadingMessageSource(),
c -> c.poller(Pollers.cron("0-7 1-59/5 * * * ?").maxMessagesPerPoll(maxFilesPerPoll)))
.channel(fileIn())
.transform(fileMessageToJobrequest())
.handle(jobLaunchingGateway())
.log()
.get();
}
I know that Spring Integration JDBC provides JDBCLockRepository but I want to know how to use the ShedLock.

It is not clear from your description how you are going to use that lock at all, but according to this article, it doesn't look like there is anything related to Spring Integration.
On the other hand, even if I'm not familiar with library, it doesn't look bad to add a LockRegistry implementation for ShedLock into Spring Integration. Although it might not be relevant to your task...

Related

Use Micrometer with OpenFeign in spring-boot application

The OpenApi documentation says that it supports micrometer. How does the integration works? I could not find anything except this little documentation.
I have a FeignClient in a spring boot application
#FeignClient(name = "SomeService", url = "xxx", configuration = FeignConfiguration.class)
public interface SomeService {
#GET
#Path("/something")
Something getSomething();
}
with the configuration
public class FeignConfiguration {
#Bean
public Capability capability() {
return new MicrometerCapability();
}
}
and the micrometer integration as a dependency
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-micrometer</artifactId>
<version>10.12</version>
</dependency>
The code makes a call but I could not find any new metrics via the actuator overview, expecting some general information about my HTTP requests. What part is missing?
Update
I added the support for this to spring-cloud-openfeign. After the next release (2020.0.2), if micrometer is set-up, the only thing you need to do is putting feign-micrometer onto your classpath.
Old answer
I'm not sure if you do but I recommend to use spring-cloud-openfeign which autoconfigures Feign components for you. Unfortunately, it seems it does not autoconfigure Capability (that's one reason why your solution does not work) so you need to do it manually, please see the docs how to do it.
I was able to make this work combining the examples in the OpenFeign and Spring Cloud OpenFeign docs:
#Import(FeignClientsConfiguration.class)
class FooController {
private final FooClient fooClient;
public FooController(Decoder decoder, Encoder encoder, Contract contract, MeterRegistry meterRegistry) {
this.fooClient = Feign.builder()
.encoder(encoder)
.decoder(decoder)
.contract(contract)
.addCapability(new MicrometerCapability(meterRegistry))
.target(FooClient.class, "https://PROD-SVC");
}
}
What I did:
Used spring-cloud-openfeign
Added feign-micrometer (see feign-bom)
Created the client in the way you can see above
Importing FeignClientsConfiguration and passing MeterRegistry to MicrometerCapability are vital
After these, and calling the client, I had new metrics:
feign.Client
feign.Feign
feign.codec.Decoder
feign.codec.Decoder.response_size

How to configure DispatcherType's for SecurityFilterAutoConfiguration?

I have a Spring Boot (2.1.5) application which uses the SecurityFilterAutoConfiguration feature. During registration of DelegatingFilterProxyRegistrationBean only REQUEST, ASYNC, ERROR DispatcherTypes are set. But I need FORWARD and INCLUDE as well.
The property security.filter-dispatcher-types from Spring Boot 1.x no longer works.
I can work around the problem by "overwriting" the DelegatingFilterProxyRegistrationBean as follows:
#Bean
#ConditionalOnBean(name = DEFAULT_FILTER_NAME)
#Primary
public DelegatingFilterProxyRegistrationBean customSecurityFilterChainRegistration(SecurityProperties securityProperties) {
DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(DEFAULT_FILTER_NAME);
registration.setOrder(securityProperties.getFilter().getOrder());
registration.setDispatcherTypes(allOf(DispatcherType.class));
return registration;
}
But that doesn't seem like a very elegant solution to me.
Is there a way to configure this for Spring Boot 2.1.x explicit?
You have to use spring.security.filter.dispatcher-types, see Spring Boot 2.0 Configuration Changelog.

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.

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