How do I use the OpenTelemetry component in Apache Camel? - spring-boot

Using the Spring Boot example from Camel, I'm trying to set up OpenTelemetry to instrument Camel.
Based on the docs, I chose the Spring Boot Auto-configuration option and added the dependency to my pom.xml.
I've also annotated the main class with #CamelOpenTelemetry:
package sample.camel;
import org.apache.camel.opentelemetry.starter.CamelOpenTelemetry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//CHECKSTYLE:OFF
/**
* A sample Spring Boot application that starts the Camel routes.
*/
#CamelOpenTelemetry
#SpringBootApplication
public class MyCamelApplication {
...
I started the application with OTEL_TRACES_EXPORTER=logging mvn spring-boot:run.
Is this correct? I'm not seeing any console output unlike this simple OpenTelemetry example.
I'm not sure if Camel 3.x is supported because this page says only 2.20+ is supported but Camel's docs says Since Camel 3.5 at the top.

Related

Migrate #EnableCircuitBreaker and #EnableEurekaClient to Spring Cloud 2022.0.1

I upgraded Spring Cloud version to 2022.0.1 and I get error for imports not found:
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
Application class:
#EnableEurekaClient
#EnableCircuitBreaker
Do you know how I can properly import them or upgrade them?
since Spring boot 2.5.12 #EnableCircuitBreaker is Deprecated, So you don't need to use it.
Also, this happened to #EnableEurekaClient and there is no need to annotate it
Just add these two dependencies to the project
spring-cloud-starter-circuitbreaker-resilience4j
org.springframework.cloud:spring-cloud-starter-netflix-eureka-client

Spring Boot's embedded Tomcat ignores access log configuration

I've enabled the access log as follows:
server.tomcat.basedir=/var/log/my-server/tomcat
server.tomcat.accesslog.directory=.
server.tomcat.accesslog.enabled=true
This usally works in my Spring Boot projects, but not in my current project (Spring Boot 2.6.6), where I'm not using #SpringBootApplication due to some limitations.
I'm currently using the following annotations for my main class:
#SpringBootConfiguration
#ComponentScan
#ServletComponentScan(basePackageClasses = { /* ... */})
#ImportAutoConfiguration({WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
ServletWebServerFactoryAutoConfiguration.class})
public class ...
Is there any autoconfiguration I need to import explicitly to configure the embedded tomcat? (server.address as well as server.port gets already respected).
You need to import EmbeddedWebServerFactoryCustomizerAutoConfiguration as well.

Spring boot auto configuration with dependency and without #ComponentScan

Spring boot provides #ComponentScan to find packages to be scanned.
I am building a library which has #RestControllers inside with package com.mylib.controller. There are other classes as well with stereotype annotations in different packages.
So, if some one is developing SpringBoot Application with com.myapp base package.
He uses my library in his application. He need to mention #ComponentScan("com.mylib") to discover stereotype components of library.
Is there any way to scan components without including library package in #ComponentScan?
As spring-boot-starter-actuator expose its endpoints just with dependency, without defining #ComponentScan. OR any default package which is scanned regardless of application base package.
You could create a Spring Boot Starter in the same style as the Spring Provided Starters. They are essentially a jar'd library with a a spring.factories file pointing to the #Configuration class to load with some other annotations on there to provide overriding/bean back off (#ConditionalOnMissingBean) and generally provide their own #ConfigurationProperties.
Stéphane Nicoll provided an excellent demo of how to build one.
https://github.com/snicoll-demos/hello-service-auto-configuration
It is also documented in the Spring Boot documentation. https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
The library approach would also work but I see no benefit in not making it a starter. Additionally for any library/starter I'd recommend dropping the #ComponentScan and just defining the beans in a #Configuration. This will work for sterotypes like #RestController etc. will function as normal if you create an #Bean out of it in a configuration.
Spring boot starter are special artifacts designed by Spring and used by Spring.
You can check that in the source code that contains mainly a
spring.provides file :
provides: spring-boot-actuator,micrometer-core
I don't know the exact way to process in the same way as Spring Boot Starter but as probably acceptable workaround, you could define in your jar a #Configuration class that specifies #ComponentScan("com.mylib").
#Configuration
#ComponentScan("com.mylib")
public class MyLibConfig {
//...
}
In this way, clients of the jar need "only" to import the #Configuration class :
#Import(MyLibConfig.class)
#Configuration
public class ClientConfig{
//...
}

Import exisiting Spring Context into Grails 3.0.1 app

I have an exisiting Spring application in Java and I want to add a Grails web app to it and reuse the domain model and my beans from the Spring context. I already created a hibernate.cfg.xml which from what I have read should integrate the domain model. But when trying to integrate the Spring ApplicationContext, I run into the following Problem/Exception:
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: A circular #Import has been detected: Illegal attempt by #Configuration class 'AppContext' to import class 'AppContext' as 'AppContext' is already present in the current import stack [ImportStack: [AppContext]]
My resources.groovy file looks like this:
beans = {
importBeans('file:grails-app/conf/spring/applicationContext-spring.xml')
}
In this xml-file, I just import my Java-config class for my Spring Java application.
I also get this circular import error when trying to define my AppContext class directly in the resources.groovy. (I assume because the code then does exactly the same.)
The error looks to me as if my AppContext is already imported by the Grais context, but when trying to use it, the beans are not present and I get the NoSuchBeanDefinitionException when trying to access them.
My question now: Does anyone know how to properly integrate my Spring context into a new Grails app?
Program version:
Java 8
Spring 4.1.0
Groovy 2.4.3
Grails 3.0.1
Gradle 2.4

How to configure JMX with Spring Boot

I have created a Spring Integration application with Spring Boot. I would like to know how to configure JMX with Spring Boot. I believe by default JMX is configured when using Spring Boot Actuator.
Do I need to configure anything else to be able to export MBeans for Spring Integration?
Most of the example I see have the following line in the applicationContext.xml
<context:mbean-export/>
<context:mbean-server/>
My Application.java class looks like this.
package com.jbhunt.app.consumerappointmentintegration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
#Configuration
#ComponentScan
#EnableAutoConfiguration
#ImportResource("classpath:META-INF/spring/integration/spring-integration-context.xml")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Adding this line to the configuration doesn't seem to export the Spring Integration mbeans
#EnableIntegrationMBeanExport(server = "mbeanServer", defaultDomain="my.company.domain")
I'm referencing this video https://www.youtube.com/watch?v=TetfR7ULnA8
As you understand the Spring Integration JMX is enabled by default, if you just have spring-integration-jmx in the classpath. And, of course, if spring.jmx.enabled = true (default).
You can't overrride that just declaring one more #EnableIntegrationMBeanExport, because it is based on #Import and you just can't override import classes because of (from ConfigurationClassParser):
imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
If imported classes are already there, they aren't overridable.
You have several choices to achieve your requirements:
Disable default Spring Boot JMX - just addind to the application.properties spring.jmx.enabled = false and continue to use #EnableIntegrationMBeanExport
Configure IntegrationMBeanExporter #Bean manually.
Just configure your my.company.domain domain in the application.properties:
spring.jmx.default_domain = my.company.domain
It is quite late to add this; but in addition to the endpoints.jmx.domain I found it useful to change the spring.jmx.default-domain to someting unique per application
This is with multiple instances of Spring Boot 1.4.1 apps running in Tomcat 7

Resources