spring-cloud how to use Endpoints - java

management endpoints:
For a Spring Boot Actuator application there are some additional management endpoints:
POST to /env to update the Environment and rebind #ConfigurationProperties and log levels
http://localhost:8080/env/testprop it works and returns:
{
"testprop": "test value"
}
but when I do POST: http://localhost:8080/env/testprop
Request method 'POST' not supported
I want to update testprop, how to do it with API?

I found the following in the docs
For a Spring Boot Actuator application there are some additional management endpoints:
POST to /env to update the Environment and rebind #ConfigurationProperties and log levels
/refresh for re-loading the boot strap context and refreshing the #RefreshScope beans
/restart for closing the ApplicationContext and restarting it (disabled by default)
/pause and /resume for calling the Lifecycle methods (stop() and start() on the ApplicationContext)
Looks like you have to post agains /env instead of /end/$yourProperty

Ok, it works:
must POST with empty body
http://localhost:8080/env/?test=dasda
and response is:
{
"test": "dasda"
}

Related

Use Spring Boot Cloud Config to change application.properties in classpath

I have to change my custom defined spring properties (defined via #ConfigurationProperties beans) during runtime of my Spring Boot application.
Is there any elegant way of doing this using Spring Cloud Config?
I don't want to use an external application.properties in a git repository (as the spring boot application gets shipped to customers and I dont' want to create a git repository for everyone of them).
I just want to access and change the local application.properties (the one in the classpath, located in src/main/resources) file in my Spring container or (if thats not possible) in the Spring Cloud Config Server, which I could embed into my Spring Boot app. Is that possible somehow?
BTW: The goal is to create a visual editor for the customers, so that they can change the application.properties during runtime in their spring boot app.
Spring Boot supports profile based application configuration. Just add application-<profile>.properties file. Then just when running the application select a profile depending on the environment making use of spring.profiles.active.
-Dspring.profiles.active=dev
This will run the application with application-dev.properties file (overriding the default application.properties, i.e you can just leave the common stuff in the default file and change the rest depending on the env)
On a side note, having a repo for configuration is not a must. You could just place them in the class path and give a search-location.
spring:
application:
name: config-server
profiles:
active: native
cloud:
config:
server:
native:
search-locations: classpath:configs/
It actually is possible and in the end quite easy to achieve. It just took me a whole day to get all the information together. Maybe this helps someone:
You basically just need Spring Actuator, but for a certain endpoint, you also need the spring cloud dependency. (to make Post requests to the /env endpoint of Spring Actuator)
To alter your config at runtime, just add the following to your application.properties:
management.endpoints.web.exposure.include: env,refresh
management.endpoint.env.post.enabled: true //this property is only available when spring cloud is added as dependency to your project
If you (like me) don't need the feature of an externalized config, then you also have to add the following (otherwise, your Spring app will not start and throw an error that some config is missing)
spring.cloud.config.enabled: false
Now, if you send a POST request to /actuator/env endpoint with an object in the HTTP body in the form of {"name":"...", "value":"..."} (name is the name of a config property), then your config gets changed. To check that, you can do a GET request to /actuator/env/[name_of_config_property] and see that your config property has changed. No need to restart your app.
Don't forget to secure the /actuator endpoint in your SecurityConfig if you use a custom one.
It seems to me that you neither need the #RefreshScope annotation at your config classes nor the /actuator/refresh endpoint to "apply" the config changes.
Maybe what your looking for could be achieved with Spring cloud config and spring cloud bus. It's explained here: https://cloud.spring.io/spring-cloud-config/reference/html/#_push_notifications_and_spring_cloud_bus
In summary, any change on configuration sent an event to the spring cloud bus and you can then reload app context or configuration with new properties.

How can I develop my own /env endpoint in Spring Boot without remove Actuator?

I have a Spring Boot application (Java 8, Spring Boot 1.5.9) with Actuator, but I need to write my own response for the /env endpoint. I tried disabling it with the property endpoints.env.enabled=false but the response that I get is an HTTP 500 instead of an HTTP 404.
Is there any way to write my own /env endpoint without remove all the Actuator library of the project?
I manage to do this in two steps:
First, re-map the /env path to something else in the application.properties file, e.g:
management.endpoints.web.path-mapping.env=default-env
Second, write our own endpoint implementation for the /env endpoint, e.g
#RestController
public class EnvController {
#GetMapping(value="/actuator/env")
public ResponseEntity<String> env() {
return ResponseEntity.ok("My custom env endpoint");
}
}

Spring Boot 2 Actuator /health endpoint not showing additional info when using authentication

I'm in the midst of migrating a project from Spring Boot 1.X to Spring Boot 2.X. The only thing that's left and that's giving me trouble is the Spring Boot Actuator.
In Spring Boot 1.X when you hit the /health endpoint with credentials, you would normally receive a more detailed list of indicators, like for example the result of the default org.springframework.boot.actuate.health.DiskSpaceHealthIndicator.
{
"status": "UP",
"diskSpace": {
"status": "UP",
"total": 1000240963584,
"free": 909162590208,
"threshold": 10485760
}
}
I would also see custom defined Health indicators here as well.
Now that I use the newer version of the Actuator library, I no longer receive that additional information (when providing credentials). All I see is:
{
"status": "UP"
}
At first I thought that maybe I haven't set up the credentials properly, but by intentionally providing invalid credentials I get 401 Unauthorized. So it can't be the authentication.
I digged in a little deeper with the debugger and saw that the DiskSpaceHealthIndicator bean actually gets created, along with all my other custom defined indicators. But it seems like they do not get registered by Spring Boot for me to not see them when hitting the /health endpoint.
Any suggestions?
The issue was fixed by adding:
management.endpoint.health.show-details=when_authorized
as #ValentinCarnu suggested.
And this is what I found afterwards in the documentation: https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html#production-ready-health
The default value is never. A user is considered to be authorized when they are in one or more of the endpoint’s roles. If the endpoint has no configured roles (the default) all authenticated users are considered to be authorized. The roles can be configured using the management.endpoint.health.roles property.
Thanks!
Don't use this URL http://localhost:8080/env
Instead use http://localhost:8080/actuator/env
And set the Application.properties with the following
management.security.enabled=false
management.endpoints.web.exposure.include=*
Worked for Me

How to disable authorization for /restart endpoint?

I try to implement restart feature in my web application.
I've added following dependencies:
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.cloud:spring-cloud-starter:1.2.4.RELEASE")
In start logs I found that post /restart was registered.
I decided to request this url:
But result is fail. I understand that this url should be protected but I have custom authorization/authentication mechanism and I don't have rights to change it.
Is there way to disable protection for this url? A better way - to have service which I can inject inside my controller and invoke. Is there something inside the spring to solve my problem?
Reason is that spring cloud enabled the security for endpoints by default.You need disable security for management (because /restart endpoint is an additional endpoint for management), in properties:
management.security.enabled=false
to remap endpoints from ../restart to /foo/restart, you need to add additional property:
management.context-path=/foo
To implement your custom end point, you just have to implement interface Endpoint and override its methods.
to disable default restart endpoint:
endpoints.restart.enabled=false
try this:
endpoints.restart.enabled = true
management.security.enabled=false

Spring Boot Actuator adding X-Frame-Options = DENY to all endpoints (particularly error endpoint)

I am attempting to set the X-Frame-Options to DENY for all management endpoints, particularly the /error endpoint. I have the following in my application.properties of my Spring Boot application.
security.headers.frame=true
management.security.enabled=true
management.port=8001
When I go to http://localhost:8001/error I do not have the X-Frame-Options header, however the http://localhost:8001/trace endpoint does have the header. How do I configure my application.properties or what do I need to override to get that response header for the error endpoint?
Going through the current Spring Boot source (1.1.7.RELEASE), I don't see anyway that you can do what you want without totally doing away with the Security auto-configuration.
That is because in order for an endpoint to be eligible for the customized HTTP Headers (like X-Frame-Options) it needs to be a bean in the parent context (the one that is associated with the application on the normal port) that implements MvcEndpoint. Such beans are HealthMvcEndpoint, JolokiaMvcEndpoint etc.
My statement adove can be viewed in code at ManagementSecurityAutoConfiguration in the ManagementWebSecurityConfigurerAdapter.configure method (endpointHandlerMapping is created from the MvcEndpoint implementation beans).
The error page for the management app, is ManagementErrorEndpoint that is created in errorEndpoint of EndpointWebMvcChildContextConfiguration which is triggered when the child context is created (due the inclusion of the management app), which is too late to be included in the endpoints that supported for HTTP Headers customization
The /error endpoint is not an Actuator Endpoint and it's not secured by default (lots of errors can happen when a user is not authenticated). You could maybe make it available to anonymous users, but my guess is not even that would prevent some nasty infinite loops, where there is a mistake in the security configuration. I'm sure there's another way to add the header without Spring Security?

Categories

Resources