how to use ApplicationEventPublisher in spring integration with annotation? - events

I am new to spring integration and I have to do some event based processing ? can anyone tell me how to use ApplicationEventPublisher. sample will be very helpful.

For publishing Spring Application events Spring Integration provides ApplicationEventPublishingMessageHandler component. This is one-way, just send producer and should be configured together with the #ServiceActivator annotations:
#ServiceActivator(inputChannel = "sendEventChannel")
#Bean
public MessageHandler eventProducer() {
return new ApplicationEventPublishingMessageHandler();
}
Also see http://docs.spring.io/spring-integration/reference/html/applicationevent.html.

Related

Spring integration : does SpringApplicationContext call #ServiceActivator in config?

I am reading Spring integration source code, and I have some questions understanding the workflow:
Does the #SpringBootApplication class, when calling application.run(), will call directly beans annotated using #ServiceActivator ? For example in my config file I have :
#Bean
#ServiceActivator(inputChannel = test)
public MessageHandler myHandler() {
return new SomeHandler();
}
when the application.run() is fired, the method handleRequestMessage() of SomeHandler will be called ? Am I understanding it right ?
Well, you need to understand that there are two parts of this matter:
Configuration phase when Spring parses all the annotations to register beans in the AppplicaitonContext. This way even that #ServiceActivator is consulted and a event-driven endpoint is registered as a bean as well.
Runtime part of Spring Integration environment. Here the mentioned endpoint is subscribed to the inputChannel and when message is has arrived the handleRequestMessage() is triggered from that SomeHandler. That's why it is called "service activator".
You probably need to make yourself familiar with EIP first of all: https://www.enterpriseintegrationpatterns.com/ to understand what is messaging and why there are endpoints and channels in between. Then you go to Spring Integration docs: https://docs.spring.io/spring-integration/docs/current/reference/html/index.html and realize for yourself that this framework provides a bunch of out-of-the-box components for this or that EIP which may be registered automaticaly in the application context by just declaring some annotation.

How to get webflux webClient metrics from custom Webclient Builder

I have created a custom Webclient Builder instead of injecting the default builder.
#Configuration
public class WebClientConfig() {
#Bean(name = "myWebClientBuilder")
public Webclient.Builder customBuilder() {
return WebClient.builder();
}
}
I have multiple services where I use this bean myWebClientBuulder and do further customization with chain of ExchangeFilterFunction.
This might not be the recommended way of using the WebClient but I would like to get some insight if there is a way to get the downstream call metrics from the Webclient based on this configuration.
Actuator Endpoint: actuator/metrics/http.client.requests
Spring Boot auto-configured WebClient.Builder is way powerful than customized version.
I tried to configure the custom builder in WebClientConfig() but it started to structure just like a copy version of WebClientAutoConfiguration. I ended up going with the spring boot autoconfigured WebClient.Builder bean.
If it helps, you can study how WebClientAutoConfiguration tries to configure webClient customizers. For metrics, it would be MetricsWebClientCustomizer.

Spring Boot metrics http.client.requests do not work for WebClient reactive applications

I have a spring boot 2.2.2 microservices, which integrations with other services using WebClient (rective). According to Spring documentation, the actuator should return "http.client.requests" metrics by default as Timer is enabled by default. But it does not work for me. I am able to get http.server.requests" metrics.
My WebClient is a bean configured and build with WebClient.builder(), as documented here: https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-metrics-http-clients
Use Spring Boot's preconfigured WebClient.Builder instead of WebClient.builder() to have an instance of WebClient.
You can find more detail here.
As in the following you can have a bean of WebClient.
#Configuration
public class ClientConfiguration {
#Bean
public WebClient webClient(WebClient.Builder webClientBuilder) {
return webClientBuilder
.baseUrl("https://example.org")
.build();
}
}
WebClient.Builder is an Auto-configuration, means the injected point above will receive a newly cloned instance of the builder.
Here is the source for WebClientAutoConfiguration
I've noticed my application has to make a WebClient call before the metrics/http.client.requests endpoint exists. Prior to my application making a WebClient call that endpoint isn't discoverable and returns NOT FOUND.
Hope that helps others in a similar situation!

Spring cloud stream kafka binder to create consumer with on demand configuration

I am using Spring boot 1.5.9.RELEASE and Spring cloud Edgware.RELEASE across the Microservices.
I've bound a consumer using #EnableBinding annotation. The annotation will do rest of the part for me to consume events.
Some requirements came up to configure the topic name and some other configuration properties manually for which I want to override some of the properties of a consumer defined in an application.properties at application boot time.
Is there any direct way to do such?
You can use an initialization bean, it can do the work:
#SpringBootApplication
public class SpringDataDemoApplication {
#Bean
InitializingBean populateDatabase() {
return () -> {
// doWhatYouWantHere...
};
}

Spring Boot Jersey and Monitoring URL's

We have a simple Spring Boot application with Jersey.
Spring Boot provides default monitoring end points
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#production-ready-monitoring
Example:
#Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
// registering resources from rest package
packages("com.xyx.abc.rest");
}
}
The REST end points that are provided by Spring Boot are not available in the context of a Spring Boot Jersey Application.
The Spring Boot dependency includes Jersey, starter-actuator, starter-tomcat.
Our REST resources show up fine, but the ones provided by Spring Boot for monitoring dont show up.
E.g http://abc.xyx.com:8080/health returns a 404
If you are using it as a Filter you need to tell Jersey not to handle those requests. E.g. by putting the Jersey resources under a separate path, like "/api/*" or something:
#Bean
public FilterRegistrationBean jersey() {
FilterRegistrationBean bean = new FilterRegistrationBean();
...
bean.setUrlPatterns(Lists.newArrayList("/api/*"));
return bean;
}
(from here).
Or by declaring that your admin endpoints are "static" (via another init parameter "com.sun.jersey.config.property.WebPageContentRegex"):
#Bean
public FilterRegistrationBean jersey() {
FilterRegistrationBean bean = new FilterRegistrationBean();
...
bean.addInitParameter("com.sun.jersey.config.property.WebPageContentRegex",
"/admin/.*");
return bean;
}
where we have set management.contextPath=/admin in the Spring Boot external configuration (otherwise you'd have to enumerate all the endpoints in the regex).
You can also tell Jersey to ignore unresolved requests (instead of sending a 404). That would also achieve your goal, but might affect your client apps (if they rely on a 404 for their behaviour).

Resources