Spring Boot 2.4.3 - Actuator /startup endpoint not found - spring

I have a spring boot app that I upgraded from v2.2.x to now be v2.4.3.
I saw in their documentation that there is a new actuator endpoint of /startup, however it does not exist when I start my app.
There is no special requirement according to their documentation here
I am using spring-boot-admin-starter-client v2.4.3 which provides spring-boot-actuator v2.4.3, and i even have management.endpoint.startup.enabled=true in my application.properties file.
Has anyone else used this version of spring boot and gotten this actuator enpoint to work?

You need to tweak startup configuration:
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setApplicationStartup(new BufferingApplicationStartup(1000));
app.run(args);
}
}
In application.properties:
management.endpoints.web.exposure.include=startup
If you want to visualize startup events check out this tool I made some months ago https://spring-boot-startup-analyzer.netlify.app/ (look at the configuration instructions as you need to enable CORS on this endpoint)

May be you are using BootstrapApplicationListener which build the application context again but ignores the previous applicationStartup, so it sets the default, this is a bug in spring-cloud-context:3.0.0

Related

Unable to access actuator endpoints when deployed on Google App Engine 11

I have an inherited spring boot application that was happily living on GAE 8 standard running on jetty. We are in the process of upgrading it to GAE 11 standard.
Based the Differences between Java 8 and Java 11/17 we determined that we would try to Migrating to Java 11/17 with bundled services and followed the instructions to Access bundled services using the App Engine APIs JAR..
The appengine-web.xml and pom.xml were updated as specified above, although we do not have a web.xml, we needed <app-engine-apis>true</app-engine-apis> to prevent some errors on start up because we previously used <sessions-enabled> to secure actuator endpoints. We do not use an app.yaml yet.
There are some release scripts in the code that suggest I should be able to access the actuator endpoints for smoke testing our DEV project to compare against our production endpoints prior to release, for instance /_ah/health, so that is where I am starting to validate my upgrade. So far...
I can access /_ah/health in our current version in production (GAE
8).
I can access /_ah/health in our current version in development
(GAE 8).
I can access /_ah/health locally on http:8080 after
clean package appengine:run (GAE 11, branch), Google App Engine
Maven plugin (deploy)
I cannot access /_ah/health and get 404 Error: Not Found when deployed to out dev (GAE 11, branch)
I've turned up the logs. I can see that is falls through several security filters but I still get a 404:
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
LogoutFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
So I am thinking this is related to the Security Configuration.
The intention is to allow the /health and /health/** for all but secure all other actuator endpoints with basic authentication (configured user/pass) in application.yml
Any help would be appreciated. Here is what I think are some valid config files. notes and logs...
All of the necessary work to upgrade the underlying spring boot application from java 8 to 11 (as suggested by many articles/checklists on the web) was completed many months ago and now we are compiling to java 11 and upgrading our GAE deployment.
appengine-web.xml updated for java 11
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<service>my-api</service>
<runtime>java11</runtime>
<instance-class>F4</instance-class>
<app-engine-apis>true</app-engine-apis>
<!-- To allow securing actuator endpoints with a login -->
<sessions-enabled>true</sessions-enabled>
<automatic-scaling>
<min-idle-instances>1</min-idle-instances>
</automatic-scaling>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties"/>
</system-properties>
</appengine-web-app>
application.yml
# ...
management:
endpoints:
web:
# GAE Standard Runtime looks for health checks under /_ah - not sure if valid any more
base-path: /_ah
exposure:
include: env,health
health:
probes:
# This enables base-path/health/liveness and base-path/health/readiness
enabled: true
# This health check will fail on GAE Standard Runtime
diskspace:
enabled: false
spring:
security:
user:
name: foo
password: bar
roles: ADMIN
# ...
SecurityConfig.java
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(final HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable()
.authorizeRequests()
.requestMatchers(EndpointRequest.to("health")).permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ADMIN")
.antMatchers("/**").anonymous()
.and().httpBasic();
}
}
Application.java
#EnableWebSecurity
#SpringBootApplication
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
// ...
}
ServletInitializer.java
Public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
As confirmed in the comments section, using an older working version of Cloud SDK (in this case v371.0.0) resulted in being able to successfully access the endpoints again.
Additionally, the issue has already been reported in the issue tracker: App Engine Standard Java 8: 404 Not Found

/startup endpoint not present in native app (using cnb and BufferingApplicationStartup)

Following the guidance here in the Spring Boot docs and having Actuator in the deps + this in main:
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Thing2Application.class);
app.setApplicationStartup(new BufferingApplicationStartup(2048));
app.run(args);
}
The /actuator/startup endpoint is present and populated when running as a standard, JVM-based (WebFlux/RSocket) app, but not when using buildpacks to create a native image. It simply doesn't appear, no indications present.
Is /startup not yet available when creating native Boot apps? If it is, please advise of any additional steps I may have missed exposing it. If not, please let me know and I'll log a request. Thanks!
That is a Spring Native bug that is being tracked in this issue.

Implement multi-tenanted application with Keycloak and springboot

When we use 'KeycloakSpringBootConfigResolver' for reading the keycloak configuration from Spring Boot properties file instead of keycloak.json.
Now there are guidelines to implement a multi-tenant application using keycloak by overriding 'KeycloakConfigResolver' as specified in http://www.keycloak.org/docs/2.3/securing_apps_guide/topics/oidc/java/multi-tenancy.html.
The steps defined here can only be used with keycloak.json.
How can we adapt this to a Spring Boot application such that keycloak properties are read from the Spring Boot properties file and multi-tenancy is achieved.
You can access the keycloak config you secified in your application.yaml (or application.properties) if you inject org.keycloak.representations.adapters.config.AdapterConfig into your component.
#Component
public class MyKeycloakConfigResolver implements KeycloakConfigResolver {
private final AdapterConfig keycloakConfig;
public MyKeycloakConfigResolver(org.keycloak.representations.adapters.config.AdapterConfig keycloakConfig) {
this.keycloakConfig = keycloakConfig;
}
#Override
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
// make a defensive copy before changing the config
AdapterConfig currentConfig = new AdapterConfig();
BeanUtils.copyProperties(keycloakConfig, currentConfig);
// changes stuff here for example compute the realm
return KeycloakDeploymentBuilder.build(currentConfig);
}
}
After several trials, the only feasible option for spring boot is to have
Multiple instances of the spring boot application running with different spring 'profiles'.
Each application instance can have its own keycloak properties (as it is under different profiles) including the realm.
The challenge is to have an upgrade path for all instances for version upgrades/bug fixes, but I guess there are multiple strategies already implemented (not part of this discussion)
there is a ticket regarding this problem: https://issues.jboss.org/browse/KEYCLOAK-4139?_sscc=t
Comments for that ticket also talk about possible workarounds intervening in servlet setup of the service used (Tomcat/Undertow/Jetty), which you could try.
Note that the documentation you linked in your first comment is super outdated!

Spring Boot Java Config Set Session Timeout

How can I configure my (embedded) Tomcat Session Timeout in a Spring Boot Application?
public class SessionListener implements HttpSessionListener{
#Override
public void sessionCreated(HttpSessionEvent se) {
se.getSession().setMaxInactiveInterval(5*60);
}
#Override
public void sessionDestroyed(HttpSessionEvent se) {
}}
I have a SessionListener but I have no idea in which class I have to add this Listener to the Context.
server.session.timeout in the application.properties file is now deprecated. The correct setting is:
server.servlet.session.timeout=60s
Also note that Tomcat will not allow you to set the timeout any less than 60 seconds. For details about that minimum setting see https://github.com/spring-projects/spring-boot/issues/7383.
Spring Boot version 1.0: server.session.timeout=1200
Spring Boot version 2.0: server.servlet.session.timeout=10m
NOTE: If a duration suffix is not specified, seconds will be used.
You should be able to set the server.session.timeout in your application.properties file.
ref: http://docs.spring.io/spring-boot/docs/1.4.x/reference/html/common-application-properties.html
EDIT:
This property has changed in later versions of Spring Boot to server.servlet.session.timeout.
ref: https://docs.spring.io/spring-boot/docs/2.4.x/reference/html/appendix-application-properties.html#server.servlet.session.timeout

Is it possible to have common xml configuration for all Cache provider vendors for jsr107

We need to have common XML configuration parameters(like timetolive) for Jcache configuration.
We are using EhCache for Development and might be using some other Jsr107 compliant cache provider, like Infinispan, in other environment.
is it possible to have single configuration file being used by both Caching provider, and we need to change only some parameters, if required, for different environment?
Is it ok to define these properties in properties file and use them to initialize Cache managers based on Profile?
I went through jsr107 documentation but didn't find common xml caching attributes.
Technology : Spring boot 1.2.3, Java 7
It really depends on what you need to use. JCache exposes a Configuration and MutableConfiguration classes that you can use to configure some settings.
Spring Boot 1.3 (about to be released) has a complete JCache integration; when you add a JSR-107 provider in your project, Spring Boot will automatically create a CacheManager for you. If you define a bean of type JCacheManagerCustomizer, it will be invoked to customize the cache manager before the application starts servicing requests.
For instance, this is a very basic configuration that changes the expiration policy:
#SpringBootApplication
#EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public JCacheManagerCustomizer cacheManagerCustomizer() {
return cm -> {
MutableConfiguration<Object, Object> configuration = new MutableConfiguration<>()
.setExpiryPolicyFactory(CreatedExpiryPolicy
.factoryOf(Duration.ONE_HOUR));
cm.createCache("foo", configuration);
};
}
}
JSR-107 does not specify anything with regards to external configuration - xml, properties, you name it.
As such any externalized configuration solution will have to be provided by your code or a framework like [Spring][1].
[1]: See Stéphane Nicoll's answer

Resources