Spring WebFlux and MVC config in the same library - spring

I'm looking for a way to implement a "switch" in my library so that it would be able to work in 2 modes - reactive and blocking.
As of now i have two libraries doing basically the same thing - set of filters and interceptors and a factory providing end user with preconfigured WebClient/RestTemplate, Authentication and Authorization.
I found that SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE) is supposed to force application to run in either a reactive or an mvc mode. However, when i add mvc-dependency i can see in log that Tomcat is being chosen as a container to run the app
Starting service [Tomcat]
Here's my pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
And the Application class
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
app.run(args);
}
}
Am i doing something wrong or the property is not supposed to allow switching between Netty and Tomcat to start with?

Related

camel mbean management objects doesn't appear by default

I use camel 3.3.0 with spring boot 2.3.1.
Considering documentation camel mbeans management objects for camel routes should be appeared by default, but it doesn't happen.
I have tried to add to application.properties all properties with jmx, but it haven't helped too.
application.properties
camel.component.jmx.customizer.enabled=true
camel.springboot.jmx-enabled=true
camel.component.jmx.enabled=true
I expect to see package org.apache.camel in Java Mission Control but I don't. I have old project with came. 2.x.x where everything works correctly.
What do I do wrong?
pom.xml
..............................
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
..............................
<properties>
<java.version>11</java.version>
</properties>
..............................
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jmx-starter</artifactId>
<version>3.3.0</version>
</dependency>
..................................
DemoApplication.java
#SpringBootApplication
public class DemoApplication extends RouteBuilder {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
public void configure() throws Exception {
from("activemq:queue:test").log("message from test");
}
}
You need to add camel-management JAR as dependency to have Camel JMX enabled.
Its also documented in the upgrade guide: https://camel.apache.org/manual/latest/camel-3x-upgrade-guide-3_1.html#_spring_boot_jmx

Camel ActiveMQ + Spring boot not reading spring activemq configurations

I am trying a very simple route with Spring Boot 1.5.2.RELEASE + Camel (Spring Boot Starter) + ActiveMQ, which is to read from a particular queue and then log it. However, it looks like it is not picking up my spring.activemq configuration for URL as I see in the log it is trying to connect to a different url and it continues to connect it and the my spring boot app never starts. The questions are based on my configuration that I am providing below how can I do the below:
Fix the configuration to allow spring's activemq configuration
Configure maxReconnectAttempts so that it does not try to connect forever if the URL is not reachable, which could be possible if the ActiveMQ instance goes down
Any assistance would be greatly appreciated. I did search relevant questions on stackoverflow but none gave me a solution to the issue I am facing
Error I am seeing on the console and this continues to like 60-70 attempts and counting. As you can see the broker URL that camel is picking up is some default URL that probably spring has configured by default
Failed to connect to [tcp://localhost:61616] after: 10 attempt(s) continuing to retry.
Here are my current configurations / code:
pom.xml - relevant portion
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud is part of the project where I am configuring camel routes -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-dependencies</artifactId>
<version>2.19.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- I have this as the same project works as a web app as well
and therefore I do not need the
camel.springboot.main-run-controller=true configuration to be set
which is as per camel's spring boot documentation-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Camel - start -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-camel</artifactId>
</dependency>
<!-- Camel - end -->
</dependencies>
application.yml (Spring Boot ActiveMQProperties)
spring:
activemq:
brokerUrl: tcp://my.company.host:[port] //This port is up and running
user: user
password: password
Camel Route in JAVA
package com.mycamel.route;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
#Component
public class SampleAmqCamelRouter extends RouteBuilder {
#Override
public void configure() throws Exception {
from("activemq:some.queue").to("log:com.mycamel.route?level=INFO&groupSize=10");
}
}
First you should add the spring-boot-starter-activemq dependency to your pom.xml. Then you can use its AutoConfiguration capabilities which will create a ConnectionFactory based on the properties you have specified in your application.yml.
After that you have to configure Camel's ActiveMQComponent too. If you would like to reuse the ConnectionFactory (which created by the autoconfig) then it can be achievable with the following:
#Configuration
public class ActiveMQComponentConfig {
#Bean(name = "activemq")
public ActiveMQComponent createComponent(ConnectionFactory factory) {
ActiveMQComponent activeMQComponent = new ActiveMQComponent();
activeMQComponent.setConnectionFactory(factory);
return activeMQComponent;
}
}
You can find more information in Camel's ActiveMQ documentation.

Spring boot , apache camel and hawtio: cannot send message to endpoint

I'm trying to integrate hawtio in a spring-boot application using apache camel. I followed Spring-Boot Embedded Wars and added HawtioConfiguration from How to run hawt.io in spring boot application with embedded tomcat (except for the kubeservice and kubepod which are not in io.hawt.web package)
So, that works, up to the point where I try to manualy send a message to a direct endpoint from the hawtio interface ( http://localhost:8080/hawtio/index.html#/camel/sendMessage?tab=camel&nid=root-org.apache.camel-camel-1-endpoints-%22direct:%2F%2Fdummy%22 ) . The following warning appears, and no message is sent:
Camel does not support sending to this endpoint.
So, did I forget anything ? Here is my set up : springboot 1.3.3.RELEASE with the following dependencies :
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.hawt</groupId>
<artifactId>hawtio-springboot</artifactId>
<version>1.4.64</version>
</dependency>
<dependency>
<groupId>io.hawt</groupId>
<artifactId>hawtio-core</artifactId>
<version>1.4.64</version>
</dependency>
and the Application.java :
#SpringBootApplication
#EnableHawtio
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Application {
#Autowired
private ServletContext servletContext;
public static void main(String[] args) {
System.setProperty(AuthenticationFilter.HAWTIO_AUTHENTICATION_ENABLED, "false");
SpringApplication.run(Application.class, args);
}
#PostConstruct
public void init() {
final ConfigManager configManager = new ConfigManager();
configManager.init();
servletContext.setAttribute("ConfigManager", configManager);
}
}
Thanks !
edit: using hawtio as a standalone app and connecting to springboot works fine
edit2: moving on, I used hawtio as a war on another project (same version) , deployed on a tomcat 7. Same issue, cannot send to a direct endpoint.
go figure.
The option of using hawtio as war works very well with application using spring boot and camel, I am already using it successfully.
check the hawtio github code example, it contains good samples to try
https://github.com/hawtio/hawtio
Also I will share my github link with sample's of using hawtio wat or as maven plug-in.
I had the same problem: I could not use hawt.io to send to a direct endpoint (nor any other endpoint). Maybe it is a general Bug/ unimplemented feature in hawt.io?
However, the following was possible:
Copy the Endpoint URL
Select the context node in hawt.io
Click on "Operations"
Use the method sendStringBody(java.lang.String,java.lang.String) to send a string to that endpoint
First parameter is the endpoint URI that you can paste in

deploy spring boot websocket sample application to tomcat7

Following tutorial helped me to get a spring boot application up and running real fast: https://spring.io/guides/gs/messaging-stomp-websocket/
But now I'm stuck trying to generate a war file and deploying it on my tomcat7 application server.
I followed the [instructions][1] to create a deployable war file, but this just isn't working. I don't see any errors in the logs, but I don't see my nice sample application either when I browse to http://localhost:8080.
Here are the steps I took to generate a war file:
1) Modify pom.xml by changing the packaging to war and marking the spring-boot-starter-websocket as provided
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
</dependency>
</dependencies>
2) Modify Application.java to override the SpringBootServletInitializer configure method.
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3) Then I run
mvn clean package
and deploy the generated war-file, but I just keep getting the default Tomcat welcome page, when I browse to http://localhost:8080/.
I also tried changing the application contextPath by adding the following application.properties:
server.contextPath=/websocketclient
server.port=8082
But this doesn't solve the problem.
I get it working, I am using Tomcat 8.
Take a look at my code here:
https://github.com/pauldeng/gs-messaging-stomp-websocket
Read and edit the pom file accordingly and run mvn package to create the package specified.
I made a mistake in my pom.xml, the provided scope shouldn't be added to the spring-boot-starter-websocket artefact. But you should add the spring-boot-starter-tomcat artefact with the provided scope.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
</dependency>
</dependencies>
I also had to modify my javascript to contact the websocket, which is now under /gs-messaging-stomp-websocket-0.1.0
var socket = new SockJS('/gs-messaging-stomp-websocket-0.1.0/hello');
The deployed application war needs to be called ROOT.war otherwise you will have to configure server.xml.
Second you should turn on the NIO connector for websockets see server.xml and http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html

Spring boot without embedded servlet container

I have a spring-boot web application, but I don't want to start it in embedded Tomcat/Jetty. What is the correct way to disable embedded container?
If I do smth like:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
I keep getting
org.springframework.context.ApplicationContextException: Unable to start embedded container;
Since you are using Maven (instead of Gradle) check out this guide and this part of the official documentation.
The basic steps are:
Make the embedded servlet container a provided dependency (therefore removing it from the produced war)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Add an application initializer like:
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class WebInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
That class is needed in order to be able to bootstrap the Spring application since there is no web.xml used.

Resources