How to Disable Spring Rest Docs - java

PROBLEM I use Spring Rest Docs in my project. It is useful at development stage, but i don't want it to be available for ordinary users and search engines in production.
RESEARCH I see no robot meta tags with content like "nocache" & "noindex". What is expected actually is maybe a spring application.property field like spring.rest-docs.enabled=false. So that I can configure it in production spring profile.
QUESTION How to disable rest docs for some spring profiles.

There were three ways to do it:
(failed) block a test with test-class annotations (couldn't setup it to work): #IfProfileValue(name = "spring.profiles.active", values = {"prod"}) or #EnabledIf("${spring.restdocs.enabled}")
(failed) configure maven-resources-plugin to work with maven-profiles and spring profiles (looked too cumbersome): https://stackoverflow.com/a/45817386/1112963
(worked) disable /resources/static folder access in application-prod.properties with spring.resources.add-mappings=false

You can add this property to your application.properties
spring.test.restdocs.failOnUndocumentedFields=false
spring.test.restdocs.failOnUndocumentedParams=false
https://scacap.github.io/spring-auto-restdocs/#_configuration
Configuration available during MockMvc setup:
failOnUndocumentedParams - if build should fail on at least one undocumented parameter
failOnUndocumentedFields - if build should fail on at least one undocumented field

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.

Property in IntelliJ: driver-class-name or driverClassName?

I use IntelliJ IDEA, the IntelliSense suggests the usage of assigning jdbc driver in application.properties file as
spring.datasource.driver-class-name=com.microsoft.jdbc.sqlserver.SQLServerDriver
See the image when I typing
But by the answer, that is wrong. It should be
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
However a web site related to JetBrains seems indicate that using driver-class-name might be correct.
https://youtrack.jetbrains.com/issue/IDEA-202820?_ga=2.207495315.1822682194.1613252382-718343134.1609267918
So I am confused. Which one is right? Is it a bug of IntelliJ IDEA?
Spring Boot supports both formats for properties, and they can be used interchangeably for properties defined by property binding (#ConfigurationProperties beans).
See also Relaxed Binding in the Spring Boot Features documentation:
Spring Boot uses some relaxed rules for binding Environment
properties to #ConfigurationProperties beans, so there does not need
to be an exact match between the Environment property name and the
bean property name. Common examples where this is useful include
dash-separated environment properties (for example, context-path
binds to contextPath), and capitalized environment properties (for
example, PORT binds to port).
In other words, given spring.datasource.driverClassName is defined through a #ConfigurationProperties bean, you can use both spring.datasource.driver-class-name and spring.datasource.driverClassName. The kebab-case form is the recommended form. The relaxed binding was - AFAIK - introduced in Spring Boot 2, so maybe the question you referenced was still at Spring Boot 1.x.
In any case, IntelliJ's autocomplete cannot be wrong in this case, because it uses information contained in the Spring Boot JAR files, generated by Spring Boot tools, specifically for spring.datasource.driver-class-name, this property name is obtained from META-INF/additional-spring-configuration-metadata.json in the spring-boot-autoconfigure JAR file. It is also the property listed in Common Application properties.
The Youtrack issue you listed seems to be an unrelated problem.

Use Spring Boot with explicitly configuration

Is it possible to use Spring Boot so that all configurations are explicitly in the main class?
For example, is it possible to tell spring-boot to print all autoconfigurations make by #SpringBootApplication so that I can copy paste in my main class?
Or is it possible to copy then from somewhere into the main?
You can have Spring Boot create a report (a list of auto configurations) simply by enabling debug mode in your application.properties file:
debug = true
The auto-configuration report contains information about the classes that Spring Boot found on the classpath and configured automatically. It also shows information about classes that are known to Spring Boot but were not found on the classpath.
And, because you've set debug=true in application.properties or application.yml, so you will see it in your output.
There is no way of doing this. Either you embrace the devil and suffer the consequences latter if you need to personalize something unpredictable by spring boot developers or you don't use it's magic.

Only overriding values with src/test/resources/application.properties for Integration test

I have an integration test that spins up a running copy of my Spring Boot rest api and performs tests with rest template. Currently I can use src/test/resources/application.properties to specify/override any properties I want to set for testing. The problem is that this doesn't only act as overriding, I have to duplicate all of the properties in src/main/resources/application.properties as well. Ideally I would like it to read both files and use the test properties to override any properties found in both files. This works for profile specific properties such as when using both src/main/resources/application.properties and src/main/resources/application-dev.properties, but doesn't seem to be the case for running tests. I know I can use a custom named properties file and pull that in with an annotation but I'd like to avoid that route to keep things clean.
I'm using Spring Boot 2.1.0.RELEASE

Disable Redis AutoConfig in spring boot when testing

I am trying to disable Redis when I am testing with spring boot. I have disabled my configuration but the auto config created a default connection and fails because it can't connect to a non-existent service. For testing I am content to just use a basic in-memory cache or a no-op cache. That doesn't work either. Here is what I have tried:
per this issue I added said configuration to my test app properties
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
But. That gets me a bit further. But ultimately I get a NoSuchBeanDefinitionException redisTemplate - this is because redisReferenceResolver is trying to look that up.
Looking at my debugger right now, the bean it's trying to hydrate is:
org.springframework.data.redis.core.convert.ReferenceResolverImpl which is coming from spring-data-redis:1.8.0.RELEASE which is coming from this dependency: compile('org.springframework.boot:spring-boot-starter-data-redis') . I admit, the bean name is a bit misleading. The type it actually resolves to is not
The only other reference to redis is in our hibernate support.
Can someone explain how to turn this off for testing?
Try excluding this two auto-configuration classes in your test properties file:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration
or
exclude
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
and set: spring.data.redis.repositories.enabled=false
With YAML syntax (& Spring Boot):
spring.autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
- org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration
If you have SystemEnvironmentPropertySource in you app context you can use environment variable SPRING_AUTOCONFIGURE_EXCLUDE separating items with comma:
SPRING_AUTOCONFIGURE_EXCLUDE=org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration
Also try #EnableAutoConfiguration(exclude = {...}) on a #TestConfiguration annotated class.
If you dont want to change any files/code, you can also do this with an environment variable:
SPRING_AUTOCONFIGURE_EXCLUDE=org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration

Categories

Resources