spring-boot - Changes to make it available to all spring-cloud-config-client - spring

We have large number of microservices which are spring cloud config client.
Each of them have bootstrap.properties which contains configuration for config server, such as URI, Username, Password for config server.
We want to overcome a problem where config client starts without actually getting the specific property resource file from config server ( some of the cases are config server was not available when client was getting started.)
So to overcome this I am thinking to use this configuration spring.cloud.config.failFast=true or to enable retry
I can do that in the bootstrap.properties for specific cloud config client or microservice.
But We have so many of them and editing the bootstrap.properties seems too much overhead
Does anyone has any other solution to the problem?
Or to apply above solution in any other place.
I am looking for a centralized solution.
Version details are as below.
<spring.version>2.4.4</spring.version>
<spring.cloud.version>2020.0.2</spring.cloud.version>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.4.4</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.3.1</version>
</dependency>

Related

Micrometer with Prometheus Pushgateway - metrics appearing in Pushgateway intermittently

I have a Spring boot application with Prometheus Pushgateway using Micrometer, mainly based on this tutorial: https://luramarchanjo.tech/2020/01/05/spring-boot-2.2-and-prometheus-pushgateway-with-micrometer.html
pom.xml has following related dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
<version>0.16.0</version>
</dependency>
And application.properties file has:
management.metrics.export.prometheus.pushgateway.enabled=true
management.metrics.export.prometheus.pushgateway.shutdown-operation=PUSH
management.metrics.export.prometheus.pushgateway.baseUrl=localhost:9091
This works fine if I leave the application running however with my particular Spring boot application, sometimes it looses the metrics sent just before the shutdown.
I can view the following logs which indicates the PrometheusPushGatewayManager is successfully calling the shutdown() method before the application shuts down which has configured with PUSH operation in the application.properties file as above:
level":"INFO","message":"Shutting down ExecutorService","file":"ExecutorConfigurationSupport.java","line_number":"208","thread_name":"Thread-1","#version":1,"logger_name":"org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager$PushGatewayTaskScheduler","class":"org.springframework.scheduling.concurrent.ExecutorConfigurationSupport"
I have tried to invoke the shutdown() method on PrometheusPushGatewayManager from my application code but still having the same issue where metrics are not appearing consistently in the Pushgateway/Prometheus (randomly).

GCloud secrets not resolving in spring properties

TL;DR: the GCP secrets are not resolved in bootstrap file but the sql starter requires an instance connection name and database name on bootstrap
I'm trying to incorporate GCP Secretmanager in a Spring Boot application that is running on Google App Engine and using the GCP SQL.
However the ${sm:// prefix doesn't seem to be resolved at bootstrap time.
For reference, this is my part of my pom. (I'm using the com.google.cloud dependencies) And I enable the spring profile "gcp"
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<relativePath/>
<version>2.4.2</version> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>2.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- ... -->
<!-- cloud -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-sql-postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
</dependency>
And in my bootstrap (for example)
spring:
cloud:
gcp:
sql:
database-name: ${sm://some-fancy-db-secret}
instance-connection-name: ${sm://some-cool-connection-name}
When deploying I get an exception stating that a database-name needs to be defined.
If I fill in the plain properties it works just fine.
Even the ${sm://db-username} works inside my application-gcp.yml file.
When I move the property from the bootstrap file it also fails.
It seems it needs the connection when bootstrapping. (I'm a bit in the dark about that)
There's no fancy multi-project going on, and yes the secret exists.
I have a feeling I'm missing something stupid here or there's a version mismatch somewhere.
(The Codelab doesn't seem to be mentioning anything special at all.)
I also checked this question. However the proposed answer doesn't seem to be valid anymore. The com.google.cloud.spring.autoconfigure.secretmanager.GcpSecretManagerProperties don't even contain a prefix property, besides it works just fine in my normal properties file.
Has been fixed in the latest release.

Spring boot server startup issue elastic search

I am using elasticsearch7.5. I have turned on the following properties
xpack.security.enabled: true
xpack.security.authc.api_key.enabled: true
I have generated API keys to connect our springboot to elasticsearch.I am using
spring-boot-starter-data-elasticsearch
All my requests are from "RestHighClient" and able to trigger the requests.Only problem is during server startup, they are some errors where it is not able to connect to Elasticsearch.
org.elasticsearch.transport.RemoteTransportException: [ADMIN-PC][127.0.0.1:9300][cluster:monitor/nodes/liveness]
Caused by: org.elasticsearch.ElasticsearchSecurityException: missing authentication credentials for action [cluster:monitor/nodes/liveness]
In pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.8.3</version>
</dependency>
in application properties:
spring.elasticsearch.server=localhost:9200
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
spring.data.elasticsearch.repositories.enabled=true
Can someone suggest me ,How I can fix it.
Remove these lines from your configuration:
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
These make Spring Boot to configure the transport client.

How does Spring Boot load changes in code without restarting the server

This was an interview question to me that , is it possible that some changes you made in your code and it is an spring boot application, and without restarting the server you are able to get those changes.?
if yes, then how is it possible in spring boot.
I want to know that how is it possible in Spring Boot.?
Add spring-boot-devtools module to your project, which includes LiveReload server which can be used to trigger a browser refresh whenever a resource has been changed.You can download browser extensions from livereload.com.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
You only need to add devtool dependency in pom.xml and yml file property:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
# for not restarting the server every time
spring.devtools.restart.enabled: false
you may want to check here spring dev tool
Notice:
no matter what, when you have change to your java code, the server need to be restarted, spring dev tool just help you to reload it
if it is jsp then you do not have to restart server.
I'm using intellij, the follow dependency setting works for me.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
Try the following steps and it should work
Add the following to pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
In application.properties
spring.devtools.restart.enabled=true
Note : Ensure spring boot is restarted once after making changes to the application.properties file.
For additional information please check
https://docs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/html/using-boot-devtools.html

Setup an embedded LDAP server with spring security using Java config

I get spring security to work with a LDAP server running on my local machine, then, I move on to finish this tutorial https://spring.io/guides/gs/authenticating-ldap/ (not step by step, since I am not using Spring boot)
The goal is to run spring security with an "embedded" LDAP server, but I am having trouble setting things up.
to summarize
locally running LDAP(get it to work) vs. embedded LDAP(having trouble)
To configure AuthenticationManagerBuilder, I did
auth.ldapAuthentication()
.contextSource()
.root("dc=oreilly,dc=com") // I didn't set url() here, so embedded server can be used
.ldif("classpath:spring-security.ldif")
.managerDn("uid=admin,ou=system")
.managerPassword("secret")
.and()
.userSearchFilter("uid={0}");
in my pom.xml, I included the following libraries
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
</dependency> <!-- This is the ldap server-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
I won't include other code here, since I get them to work with a local LDAP.
When I run, I get the following error:
java.lang.NoClassDefFoundError:
org/apache/directory/server/core/partition/Partition
I think I may miss to include some libraries, but not sure which..
After trying different setting, this works for me:
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-protocol-ldap</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.directory.shared</groupId>
<artifactId>shared-ldap</artifactId>
<version>0.9.15</version>
</dependency>

Resources