SpringBoot - SpringFox Starter 3.0.0 - Unable to detect WebFlux RouterFunction - spring-boot

I am using SpringBoot WebFlux Springfox-starter for the project.
The issue is this not detecting the RouterFunction methods. The above methods are detecting without any issues but it is not working for RouterFunctions.
#Bean
public RouterFunction<ServerResponse> route(GreetingHandler greetingHandler) {
return RouterFunctions
.route(RequestPredicates.GET("/hello")
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
greetingHandler::hello);
}
#Component
public static class GreetingHandler {
public Mono<ServerResponse> hello(ServerRequest request) {
return ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(BodyInserters.fromValue("Hello, SpringFox!"));
}
}
https://github.com/springfox/springfox
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
I have hosted the entire project in the below location. Please let me know if anyone experience the same or additional configuration missing here.
https://github.com/chamithchathuka/demowebflux-2
https://github.com/chamithchathuka/demowebflux-2/tree/master

Related

How to correctly handle "FeignException$ServiceUnavailableException" with fallback and without deprecated #EnableCircuitbreaker annotation

When using OpenFeign I implement fallbacks returning empty results so lists should simply appear as being empty. E.g. such as
#FeignClient(name = "objects", fallback = ObjectsClientFallback.class)
public interface ObjectsClient {
#RequestMapping("/objects/count")
Long count();
}
and
#Component
public class ObjectsClientFallback implements ObjectsClient {
#Override
public Long count() {
return 0L;
}
}
However, if the service is not started the application produces the ServiceUnavailableException when calling objectsClient.count() instead of using the fallback.
What is the correct way to use the fallback as #EnableCircuitBreaker has been deprecated recently? I do not want to add try-catch blocks if possible, especially in the context of lambdas or wrap this in service methods.
The application uses the #EnableDiscoveryClient annotation, like so
#SpringBootApplication
#EnableJpaRepositories
#EnableFeignClients
#EnableDiscoveryClient
#ServletComponentScan
public class Application {
//..
}
I've seen this question and checked the mentioned documentation, but it didn't help. Library versions are Spring-Boot 2.6.2 and Spring-Cloud 2021.0.0
Ended up using resilience4j for spring cloud.
Next to feign.circuitbreaker.enabled=true in application.properties which sets up a circuitbreaker with a default config.
One can add a custom configuration like this:
#Configuration
public class FeignConfiguration {
#Bean
public Customizer<Resilience4JCircuitBreakerFactory> circuitBreakerFactoryCustomizer() {
CircuitBreakerConfig circuitBreakerConfig =
CircuitBreakerConfig.custom()
.ignoreException(FeignException.ServiceUnavailable.class::isInstance)
.build();
return circuitBreakerFactory -> circuitBreakerFactory
.configure(builder -> builder.circuitBreakerConfig(circuitBreakerConfig),
ObjectsClient.class.getSimpleName());
}
}
Also, the resilience4j dependency needs to be in place, here a maven pom.xml is used.
<project>
<!-- .. -->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
</dependencies>
That way you can replace the deprecated hystrix implementation and remove the #EnableCircuitBreaker annotation.
In case you want a more fine-grained setup, here are is a discussion how to implement fallback with resilience4j via default methods.

SpringBoot application monitoring Adding Timed annotation cause to error

I'm implementing micrometer to spring web project. While trying to add #Timed annotation. Prior to add #Timed i'm supposed to create TimedSpect bean. But it says could not autowire no bean of MeterRegistry type found
#Configuration
public class MetricsCofiguration {
#Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
Not sure if you still need this answer but this is what i tried and its working fine.
#Configuration
#EnableAspectJAutoProxy
public class TimedConfiguration {
#Autowired
MeterRegistry registry;
#Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
Make sure you have below starter dependency in your pom.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Spring MVC Neo4jConfiguration class not found

I am learning Spring MVC. I want to extend the Neo4jConfiguration class but it is not available. I imported the following dependency:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
and after that I have reimported the libraries from maven. As I know I should now be able to extend the Neo4jConfiguration class. What is the problem? Thank you!
Neo4jConfiguration has been dropped from Spring Data Neo4j 4.2.
You can refer to the 'Configuring a Simple Spring Application' and 'Configuring Web Applications' in the Upgrading to Spring Data Neo4j 4.2 for a quick configuration without it.
The code sample they provide for simple configuration is:
#Configuration
#EnableNeo4jRepositories(basePackages = "org.neo4j.example.repository")
#EnableTransactionManagement
public class MyNeo4jConfiguration {
#Bean
public SessionFactory sessionFactory() {
// with domain entity base package(s)
return new SessionFactory("org.neo4j.example.domain");
}
#Bean
public Neo4jTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
}

Spring boot & Swagger 2 UI & custom requestmappinghandlermapping - mapping issue

I have own RequestMappingHandlerMapping and I am using springfox-swagger-ui. After adding my custom mapping, I am not able to achieve swagger ui at http://localhost:8080/swagger-ui.html.
Any ideas?
This is my configuration.
#Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
#Override
#Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return new ApiVersionRequestMappingHandlerMapping("v");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("(META-INF/resources/webjars");
}
}
Here's my pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
When you override WebMvcConfigurationSupport, you are also overriding spring Boot's mvc auto configuration (WebMvcAutoConfiguration). Therefore, resources that need spring boot's configuration will not work. This is not a problem specific to swagger.
You can find more info about this here:
https://github.com/spring-projects/spring-boot/issues/5004
As the github issue suggests, there will be changes on this in the future to make it easier. Currently there are some workarounds, as suggested there.
A quick and dirty way of doing this is by copying and pasting the WebMvcAutoConfiguration class into your own class, returning your own HandlerMapping from the requestMappingHandlerMapping() method of EnableWebMvcConfiguration and registering the copy of the WebMvcAutoConfiguration as an auto configuration class. You can see instructions here:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
Make sure you place your copy of the WebMvcAutoConfiguration at some package which is not component scanned and picked up automatically. It should just be registered as explained in the above link.
Also make sure you set the order of you custom HandlerMapping to 0 before returning it from the requestMappingHandlerMapping() method, like so:
#Bean
#Primary
#Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// Must be #Primary for MvcUriComponentsBuilder to work
ApiVersionRequestMappingHandlerMapping handlerMapping = new ApiVersionRequestMappingHandlerMapping("v");
handlerMapping.setOrder(0);
handlerMapping.setInterceptors(getInterceptors());
handlerMapping.setContentNegotiationManager(mvcContentNegotiationManager());
PathMatchConfigurer configurer = getPathMatchConfigurer();
if (configurer.isUseSuffixPatternMatch() != null) {
handlerMapping.setUseSuffixPatternMatch(configurer.isUseSuffixPatternMatch());
}
if (configurer.isUseRegisteredSuffixPatternMatch() != null) {
handlerMapping.setUseRegisteredSuffixPatternMatch(configurer.isUseRegisteredSuffixPatternMatch());
}
if (configurer.isUseTrailingSlashMatch() != null) {
handlerMapping.setUseTrailingSlashMatch(configurer.isUseTrailingSlashMatch());
}
if (configurer.getPathMatcher() != null) {
handlerMapping.setPathMatcher(configurer.getPathMatcher());
}
if (configurer.getUrlPathHelper() != null) {
handlerMapping.setUrlPathHelper(configurer.getUrlPathHelper());
}
return handlerMapping;
}
It works for me.
Overriding addResourceHandlers instead of registering auto-configuration.
Github Source
#Configuration
#EnableWebMvc
#EnableSwagger2
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
Overriding requestMappingHandlerMapping() of WebMvcConfigurationSupport will turn off spring boot's auto configuration. For adding custom MVC Components you may use WebMvcRegistrations. Like, for providing custom RequestMappingHandlerMapping, We may override getRequestMappingHandlerMapping(), with custom RequestMappingHandlerMapping, ofWebMvcRegistrationsAdapter and provide it through webMvcRegistrationsHandlerMapping(). As,
#Configuration
class CustomRequestMappingHandlerMapping {
#Bean
public WebMvcRegistrationsAdapter webMvcRegistrationsHandlerMapping() {
return new WebMvcRegistrationsAdapter() {
#Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new ApiVersionRequestMappingHandlerMapping("v");
}
};
}
}
In Spring Boot 2.0.0, there is a simpler way to achieve this.
Create an instance of WebMvcRegistrations interface as a bean and override appropriate method to return the customized version of that object. Spring boot will read and use that instance.
In this case only the getRequestMappingHandlerMapping() needs to be overridden and a custom implementation returned
Above information is from a follow through based on the links provided by #Nazaret K.
More information at https://github.com/spring-projects/spring-boot/issues/5004
It can be solved by using WebMvcConfigurationSupport with adding resource handlers for swagger:
#Configuration
public class MvcConfiguration extends WebMvcConfigurationSupport {
#Value("${spring.application.name}")
private String applicationName;
//...irrelevant code here
#Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
I finally find it!
The right configuration is this:
#Configuration
public class VersioningMappingHandlerConfig {
#Bean
public ApiVersionRequestMappingHandlerMapping customMappingHandlerMapping() {
ApiVersionRequestMappingHandlerMapping handler = new ApiVersionRequestMappingHandlerMapping("v", 1, 1);
handler.setOrder(-1);
return handler;
}
}
Note: there is no extends WebMvcConfigurationSupport and bean name is customMappingHandlerMapping

Query parameters reading spring integration

I am new to Spring Integration, I just started looking into the specification. My requirement is to get the HTTP request
(example : http://localhost:8080/LoginCheck?name=xyz&dob=zyz).
Can anybody guide me, how to proceed as i googled and found some information that we can use inbound gateway to read the parameters, my requirement like get the Http client data and do some process and finally respond to client in XML format.
I got stucked in reading the input data only.
You have to get the payload of the received message. There should be a Map with the request parameters.
I have made a simple SI DSL application that does just that
#SpringBootApplication
public class JmsResponderApplication {
public static void main(String[] args) {
SpringApplication.run(JmsResponderApplication.class, args);
}
#Bean
public HttpRequestHandlingMessagingGateway httpGate() {
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
RequestMapping requestMapping = new RequestMapping();
requestMapping.setMethods(HttpMethod.GET);
requestMapping.setPathPatterns("/foo");
gateway.setRequestMapping(requestMapping);
gateway.setRequestChannel(requestChannel());
return gateway;
}
#Bean
public DirectChannel requestChannel() {
return MessageChannels.direct().get();
}
#Bean
public IntegrationFlow flow() {
return IntegrationFlows.from(requestChannel())
.handle(new MessageHandler() {
#Override
public void handleMessage(Message<?> m) throws MessagingException {
Object payload = m.getPayload();
System.out.println(payload); // the payload is a Map that holds the params
System.out.println(m);
}
})
.get();
}
}
It's a simple Spring boot starter project with this dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-java-dsl</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Source - here

Resources