Spring Boot 2 Actuator Config Property Sources Not Found - spring

I've been trying to migrate from Spring Boot 1.x to Spring Boot 2.4.2.
I have a problem with /health endpoint of actuator which says:
"clientConfigServer": {
"status": "UNKNOWN",
"details": {
"error": "no property sources located"
}
}
in active profile native. For older version everything worked as expected and I was receiving:
"configServer": {
"status": "UP",
"propertySources": [
"file:C:\\Users\user\projects\tagging.yml",
]
}
Is this a bug or I am doing something wrong?

Related

Centralized Swagger/OpenAPI UI for all the different microservices on a single swagger URL i.e accessing all the URLs through one

I have around 16 microservices built in Spring Boot that communicate with each other and each microservice is having multiple APIs in it. I have configured OpenAPI for each of the microservices. So it gives me 16 "swagger-ui" URLs.
I wonder how can I centralize all Swagger URLs on one single page; I want only 1 swagger URL to access all the 16 microservices.
I have gone through the following as well but didn't get any solution
Centralize Swagger at one place for All microservices
Please guide me to the best way to achieve it.
I found a working solution on GitHub. It works with Spring Cloud Discovery but can be easily adapted to other discovery solutions. The basic idea is to generate for Swagger the list of URLs pointing to the OpenAPI JSON files.
The result is similar to one in the #shadyx's answer, but the list is generated dynamically
#RestController
public class SwaggerUiConfig {
#Autowired
private DiscoveryClient discoveryClient;
#GetMapping("/swagger-config.json")
public Map<String, Object> swaggerConfig() {
List<SwaggerUrl> urls = new LinkedList<>();
discoveryClient.getServices().forEach(serviceName ->
discoveryClient.getInstances(serviceName).forEach(serviceInstance ->
urls.add(new SwaggerUrl(serviceName, serviceInstance.getUri() + "/v3/api-docs"))
)
);
return Map.of("urls", urls);
}
}
application.yaml
springdoc:
swagger-ui:
configUrl: "/swagger-config.json"
Sample of the generated swagger-config.json
{
"urls": [
{
"url": "http://localhost:8088/v3/api-docs/users",
"name": "users"
},
{
"url": "http://localhost:8088/v3/api-docs/stores",
"name": "stores"
}
]
}
If all you µservices use the same host, you can create a Spring Boot µservice which acts as a openAPI gateway using spring-doc. (If they are not using the same host, you will have to deal with CORS issues)
First, add the following dependencies to your new gateway µservice
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Then, add the below configuration
springdoc:
api-docs:
enabled: true
swagger-ui:
configUrl: ${server.servlet.contextPath}/v3/api-docs/swagger-config
url: ${server.servlet.contextPath}/v3/api-docs
urls:
- name: api-customer
url: /customer/v3/api-docs
- name: api-cart
url: /cart/v3/api-docs
- name: api-product
url: /product/v3/api-docs
For each µservice you have to fill in the url property with is the url to the openAPI definition at json or yaml format.
For springdoc library which uses openAPI 3.0 the default url is /${µServiceContextPath}/v3/api-docs
For springfox library which uses openAPI 2.0 the default url is /${µServiceContextPath}/v2/api-docs
Finally access to /${contextPath}/swagger-ui.html and you will be able to select an openAPI

Spring Boot actuator endpoint /prometheus doesn't list the tomcat related metrics, like request count

Spring Boot actuator endpoint /prometheus doesn't list the tomcat related metrics, like request count. But it has metrics like http_server_requests_seconds_count and http_server_requests_seconds_max.
The endpoint /actuator/metrics/http.server.requests returns the request count metrics -
"measurements": [
{
"statistic": "COUNT",
"value": 268.0
},
{
"statistic": "TOTAL_TIME",
"value": 6.888039926
},
{
"statistic": "MAX",
"value": 0.002780578
}
]
We are using Spring Boot 2.x and the actuator dependency is defined as -
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Is there anything missing?
You need to enable Tomcat’s MBean registry:
server.tomcat.mbeanregistry.enabled must be set to true for all Tomcat metrics to be registered

Spring Config Client Not able to Fetch Configs from Server

My Spring Cloud config client is not able to resolve the server1 property. It is throwing "Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'server1' in value "${server1}""
#Controller
#RefreshScope
public class OSLController {
#Value("${server1}")
public String oslServer;
}
Here is the bootstrap.properties of the config client:
spring.cloud.config.uri=http://localhost:8888
spring.profiles.active=preprod
spring.application.name=osl
Here are the configurations of the config server:
application.properties
server.port=8888
spring.profiles.active=native
spring.cloud.config.server.native.searchLocations=classpath:/config/osl,classpath:/osl,classpath:/config
Here are the paths when hit by the browser:
http://localhost:8888/osl/preprod
{
"name": "osl",
"profiles": [
"preprod"
],
"label": null,
"version": null,
"state": null,
"propertySources": [
{
"name": "class path resource [config/osl/osl-preprod.properties",
"source": {
"server1": "preprod"
}
},
{
"name": "class path resource [config/osl/osl.properties",
"source": {
"server1": "common"
}
}
]
}
When the config client is started, it prints the following logs:
2021-02-27 19:19:06.576 INFO 27040 --- [ main] in.rahul.ConfigClient2Application : Starting ConfigClient2Application using Java 15.0.1 on DESKTOP-CJ4TSGP with PID 27040 (C:\Rahul\Workspace\ConfigClient-2\target\classes started by Rahul in C:\Rahul\Workspace\ConfigClient-2)
2021-02-27 19:19:06.579 INFO 27040 --- [ main] in.rahul.ConfigClient2Application : No active profile set, falling back to default profiles: default
2021-02-27 19:19:07.282 INFO 27040 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=d5ff5a52-737f-3fd5-8528-04cdeb4cd847
2021-02-27 19:19:07.475 INFO 27040 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
The tutorial that I am following prints the following as well while starting the config client
Fetching config from server at: http://localhost:8888/
The above message is not coming in my config client which is leading me to believe that config client is not able to recognize the config server.
Can someone please guide the problem and how to troubleshoot this? If I am able to read the configs from browser why the client is not able to connect and resolve the server1 property.
I am using windows machine.
Thanks.

Spring Boot Actuator Trace HTTP POST request parameters is coming empty

I am using Spring Boot 1.5.13 so using Actuator 1.5.13 . When i call with the post request ,request parameters is coming empty.
No other configuration or createing my Actuator repository.
I just using simple actuator trace end point.
Here is my properties:
endpoints.trace.enabled=true
endpoints.trace.sensitive=false
management.trace.include=request-headers,response-headers,cookies,errors,parameters
Here is the dependency :
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Trace result :
parameters {}
Request Example :
{
"id": 22,
"secondid":350052 ,
"flag":0
}
Do you have any idea why it is happening and how i can fix it?
The parameters that are traced are those that are available from javax.servlet.ServletRequest.getParameterMap(). From its javadoc:
Request parameters are extra information sent with the request. For HTTP servlets, parameters are contained in the query string or posted form data.
Your HTTP request doesn't have a query string and it isn't POSTing form data so there are no parameters to trace.
For example if request is like /api/persons?name=peter, parameters will be available in the trace.
"parameters": {
"name": [
"peter"
]
}

Cannot disable Spring Cloud Config via spring.cloud.config.enabled:false

Let me preface this by saying that I'm not using Spring Cloud Config directly, it is transitive via Spring Cloud Hystrix starter.
When only using #EnableHystrix, Spring Cloud also tries to locate a configuration server, expectedly unsuccessfully, since I'm not using one. The application works just fine, as far as I can tell, but the problem is in the status checks. Health shows DOWN because there is no config server.
Browsing the source of the project, I'd expect spring.cloud.config.enabled=false to disable this functionality chain, however this is not what I'm seeing.
After upgrading to 1.0.0.RC1 (which adds this property) and using #EnableCircuitBreaker:
{
status: "DOWN",
discovery: {
status: "DOWN",
discoveryClient: {
status: "DOWN",
error: "org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.cloud.client.discovery.DiscoveryClient] is defined"
}
},
diskSpace: {
status: "UP",
free: 358479622144,
threshold: 10485760
},
hystrix: {
status: "UP"
},
configServer: {
status: "DOWN",
error: "org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http: //localhost: 8888/bootstrap/default/master":Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect"
}
}
After checking the configprops endpoint, it seems that my properties are being overridden. Note that the parent has the configClient enabled.
parent: {
configClientProperties: {
prefix: "spring.cloud.config",
properties: {
password: null,
discovery: {
enabled: false,
serviceId: "CONFIGSERVER"
},
name: "bootstrap",
label: "master",
env: "default",
uri: "http://localhost:8888",
enabled: true,
failFast: false,
username: null
}
}
},
configClientProperties: {
prefix: "spring.cloud.config",
properties: {
password: null,
discovery: {
enabled: false,
serviceId: "CONFIGSERVER"
},
name: "bootstrap",
label: "master",
env: "default",
uri: "http://localhost:8888",
enabled: false,
failFast: false,
username: null
}
}
Any direction would be appreciated, if it seems I'm not doing this correctly.
The config server is needed during bootstrap, and that's where the parent property sources come from. It looks like all you need to do is move your spring.cloud.config.enabled property to bootstrap.yml (or .properties).
You can put a bootstrap properties or yml to your resource direcotry
or your applications directory and add
spring.cloud.config.enabled=false. OR
You can disable spring cloud config server client by adding an environment variable: SPRING_CLOUD_CONFIG_ENABLED=false OR
Config server client can be disabled by adding a parameter to your app, if you pass the args to parameters to SpringApplication.run:
public static void main(String[] args) throws Exception {
SpringApplication.run(YourApplication.class, args);
}
and start the app by:
java -jar yourapplication.jar --spring.cloud.config.enabled=false
I had the same problem, I wanted to have the config server disabled (as we do not need it so far) but the property mentioned above is not correct for RC1 at least.
spring.cloud.enabled
Should be:
spring.cloud.config.enabled
I tried all of the above changes and still config client never stopped somehow.
The only way I was able to disable it by using following exclusion in my project's pom.xml file.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</exclusion>
</exclusions>
</dependency>
Regarding the discovery service followup (looks like no other posts on that), setting spring.cloud.config.discovery.enabled: false worked for me, but only if it was set in bootstrap(yml/properties) and if I removed the #EnableDiscoveryClient annotation from my Application class. I guess this means one cannot use that annotation for any service where discovery will not be used at times.
None of those has helped me, I needed to disable spring cloud client bootstrap from server for my integrations tests, so whoever faces the same issue may use what as helped me:
#ComponentScan(excludeFilters = {
#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = PropertySourceBootstrapConfiguration.class),
})
public class TestApplication {
}
and than annotate your tests with:
#SpringBootTest(classes = TestApplication.class)
class SomeIntegrationTest {}

Resources