How to activate JMX monitoring in spring boot standalone app - java

I went via almost all docs and all but not able to get grip on this mysterious stuff.
so my question - Can I use my standalone spring boot app to monitor health and other metrics of my app via http jmx url? Do I need to configure something else for this?
I have added below dependency in boot app.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
I have also configured below properties in my config file.
management.endpoints.web.exposure.include=*
management.endpoints.jmx.unique-names=true
management.server.port=8080
management.server.ssl.enabled=false
When I try to hit URL : http://localhost:8080/actuator/jolokia/health I am not able to see any results.
Also tried adding custom end point like below but not working.
#Endpoint(id="mypoint")
#Component
public class myPointEndPoint {
#ReadOperation
public String mypoint(){
return "Hello" ;
}
with additional property
management.endpoint.mypoint.enabled=true

The problem is the url you are trying to invoke.
First, retrieve the possible mbeans with: http://localhost:8080/actuator/jolokia/list
When you take a look at the Health mbean, you must provide the unique name and the operation (op).
In my case, it looked like: http://localhost:8080/actuator/jolokia/exec/org.springframework.boot:type=Endpoint,name=Health,identity=4200098/health
Also check the Jolokia documentation: https://jolokia.org/reference/html/index.html

Related

Which JWT + Spring Security configuration method is relevant right now?

At the moment I am developing an authorization server using spring security + OAUTH2 and JWT, but in the examples there are many different ways, some of them are deprecated.
Tell me, please, the most current?
When creating a project, I plug dependency the Cloud OAuth2, then a dependency appears in
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
I also customize the annotating #EnableAuthorizationServer
I use this method, tell me how relevant is it?
I saw other ways where it was necessary to register and configure filters, providers, etc., this is closer to me, but I don’t understand which option is the most relevant now.

How to get metrics of outgoing http calls in Spring Boot?

My Spring Boot application calls other providers and I'd like to measure the time a response takes, but also would nice to measure other stuff. Is there a clean way of doing this maybe some library or package?
I'd need something which integrates seamlessly with existing apps, and I do not need to wrap the calls with System.getCurrentTimeMillis() etc.
You can use Spring Actuator,Prometheus Server/Client and Grafana Server to monitoring your application. There are 4 types of metrics available in Prometheus, you can use according to your requirements.
Prometheus Documentation
https://prometheus.io/
Grafana Documentation
http://docs.grafana.org/
Install Prometheus and Grafana servers.
You have to add the dependencies for Prometheus Client. Also Spring Actuator dependency need to add.
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_spring_boot</artifactId>
<version>0.0.26</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.0.26</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_servlet</artifactId>
<version>0.0.26</version>
</dependency>
In Configuration file you have to define bean for metrics.
#Bean
public ServletRegistrationBean servletRegistrationBean() {
DefaultExports.initialize();
return new ServletRegistrationBean(new MetricsServlet(), "/prometheus");
}
You can follow https://g00glen00b.be/monitoring-spring-prometheus-grafana/ for more detail.
Prometheus can monitor some metrics in the jvm.
But you may want to see the javamelody spring-boot-starter which will give metrics on the jvm and on the application and also on #Service Spring components and on RestTemplate when defined as bean to measure calls to some other providers.

Spring boot - Rest Call client without embedded tomcat

I have been trying to figure out an issue with spring boot and as i am new to spring I thought of getting some help here.
I have a spring boot based java application which runs as a daemon and makes some GET request to a remote server. (Acts only as a client).
But my spring boot application internally starts an embedded tomcat container.
My understanding is that if the java app acts as a server, it would need tomcat. But my application being only a consumer of remote machine's GET APIs, why would it need an embedded tomcat ?
In my pom file I have specified spring-boot-starter-web,
on assumption that it is needed for even making GET calls.
But after doing some research on disabling embedded tomcat, I found a solution.
To make following changes,
#SpringBootApplication(exclude = {EmbeddedServletContainerAutoConfiguration.class,
WebMvcAutoConfiguration.class})
&
in application.yml
spring:
main:
web-environment: false
With the application.yml changes, my jar is not even getting started, aborts directly, without even logging anything in logback logs.
Now, if i remove the application.yml change, my jar starts (only with first change in #SpringBootApplication anno.) but goes into some exception.
[main] o.s.boot.SpringApplication : Application startup failed
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
My Doubts here are,
1) Is tomcat, be it standalone or embedded, really needed for a application which just makes GET API calls to remote machine ?
2) How do i overcome this exception and safely remove the embedded tomcat and still perform the GET API calls ?
You seem to be on completely the wrong track here, starting from a web application template and then trying to turn off the web application aspect.
Far better to start from a regular commandline client template and go from there, as detailed in the relevant Spring Guide.
Basically the application reduces to
#SpringBootApplication
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String args[]) {
SpringApplication.run(Application.class);
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
#Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
};
}
}
And the pom to
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
I had this problem. All I wanted was to have a Client making REST requests. Unfortunately I had a dependency which was embedding Jetty, and Jetty was always started.
In order to disable Jetty all I needed to do was to add in applications.properties the following entry:
spring.main.web-application-type=none
That fixed it.
Here is the most simple solution for me, make spring boot application just a restful api consumer.
Replace the dependence
implementation("org.springframework.boot:spring-boot-starter-web")
with
implementation("org.springframework.boot:spring-boot-starter-json")
RestTemplate and jackson are available in the project without embedded tomcat.
Answering your questions:
1) embedded by defaut - not needed for clients HTTP requests;
2) You can use CommandLineRunner for spring boot applications without any web:
#SpringBootApplication
public class SpringBootConsoleApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(SpringBootConsoleApplication.class, args);
}
#Override
public void run(String... args) {
// TODO: start you thread here to execute client HTTP REST requests (or any other job you need)
}
}
This will disable web completelly - no issues with manual miss-configuration.
Here is some docs:
http://www.baeldung.com/spring-boot-console-app
You also need replase spring-boot-starter-web dependency with spring-boot-starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
From your question, i assume you want your application to keep running in background and it makes some get calls in it's life cycle. If that's the case, then
answering your first question, yes, you need an embedded tomcat or
jetty or need to deploy your application to an external application
server.
Second, to get rid of the exception your facing, don't exclude
EmbeddedServletContainerAutoConfiguration and
WebMvcAutoConfiguration class as it's needed for default embedded
tomcat auto configuration.

How to monitor Apache camel routes in a Java project using hawtio

Usually if we develop a java camel application using Java DSL then its very difficult to monitor the camel routs. To check whether the routes are running or not we need an extra monitoring application need to be developed.
But Hawtio ease our work in that. If your project is web application project then Hawtio has already camel component for it. So with out any extra efforts it will directy work.
But for Java Application it is not showing the routes.
When we develop a java camel application we need some extra works to be done in order to view the routs.
Steps for configuring java related camel application on hawtio
Download the hawtio from https://hawt.io/getstarted/
Place the war file in tomcat webapps folder --> start the tomcat web server.
( If you don’t have tomcat then please download the same from https://tomcat.apache.org/download-80.cgi )
Goto: http://localhost:8080/sample-1.5.6/welcome to view the hawtio
Note: At the first time there will be no Container tab.
To make use of hawtio in JVM (for java related application) we use Jolokia.
Download Jolokia from https://jolokia.org/download.html
Command to attach Jolokia on the fly (No code changes required). We can use same jar file for deployment purposes.
Use the following command line argument:
java <location of Jolokia agent.jar file> =host=0.0.0.0 -jar <location of our jar file>
Example:
java -javaagent:jolokia-jvm-1.4.0-agent.jar=host=0.0.0.0 -jar C:\Users\HackoMan\Documents\GitHub\target\myjar-1.0-SNAPSHOT.jar
Goto: http://localhost:8080/sample-1.5.6/welcome hawtio --> Connect --> Discovery --> press run/play button as mentioned below.
This opens a new tab. Press camel tab to view all of our route.
Then click on any route that either you want to debug or trace or to find details about it.
I was stuck doing this. After reading some documentation and blogs I could monitor Camel routes using Hawtio.
Spring Boot 2.3.4.RELEASE
Camel 3.4.3
Hawtio 2.10.1
Dependencies
For Spring Boot, it's not necessary if you already have conifgured the project.
Auto-detects camel routes in Spring Context and register Camel utilities
(like producer template, consumer template and the type converter) as beans.
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot</artifactId>
<version>${camel.version}</version>
</dependency>
To have support for auto-configuration from properties
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>${camel.version}</version>
</dependency>
For manage routes using Jolokia as agent.
To allow camel routes been manage by jolokia
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-management</artifactId>
<version>${camel.version}</version>
</dependency>
To run jolokia and expose metrics over Http
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Properties
Expose Jolokia endpoint
management.endpoints.web.exposure.include=jolokia
For not to use the word "actuator" as part of the endpoint when exposing jolokia
management.endpoints.web.base-path=/
For configuring Jolokia endpoint path
management.endpoints.web.path-mapping.jolokia=medidas
For setting custom port
server.port=8778
Finally
Start the project
Start Hawtio
java -jar hawtio-app-2.10.1.jar
In web broser
http://localhost:8080/hawtio
Configure the connection, test the connection.
Connection Picture
The last step is connect and automatically you will see camel routes
Add follwoing dependency to spring boot app.
  <dependency>
 <groupId>io.hawt</groupId>
<artifactId>hawtio-springboot</artifactId>
</dependency>
Add following properties for getting started without auth.
hawtio.authenticationEnabled = false
hawtio.offline = true
Complete example available over here:
https://github.com/jinternals/camel/

Apply /refresh on multiple instances annotated with #refreshScope

I'm writing spring boot application, which using spring configuration, deployed on pivotal cloud foundry and exposed by Netflix Eureka as discovery serivce / load balancer.
I have created a bean as followed:
#Component
#ConfigurationProperties("config")
#RefreshScope
#Data
public class GeneralProperties {
private boolean ignoreEvent;
}
When calling to the application route that Eureka exposed with /refresh after changing the actual property in the configuration repository, the value that annotated by #refreshScope was changed (end in the response status the field exsiting), which means it's working correctly.
The issue starts when running multiple instances of the same application on the cloud, and calling to the /refresh.
The route that beeing used is the one that exposed by Eureka, which using it's load balancer to route the call to one of the available instances.
It leads to unexpected results that not all the instances are getting updated with the latest change in the property.
Any suggestions how to apply the change on all instances?
You should use Spring Cloud Bus in such a case.
The idea behind this framework is to bind all your application instances to a topic in a message broker (RabbitMQ or Apache Kafka).
Add the following dependency to your pom.xml:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus-parent</artifactId>
<version>1.3.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
</dependencies>
In the above example I added a dependency on amqp which is RabbitMQ. You'll also need to bind your application to the RabbitMQ, in PCF it's easy since it's built in to the platform.
When you need to refresh, you should invoke:
POST /bus/refresh
This would trigger an event to a topic that all instances of your application are listening to, and as a result - all instances would refresh their bean configuration.
Good luck.

Categories

Resources