Last Updated on July 9, 2023 by KnownSense
Objective:
To create an aot native-image of a java based Microservice in SpringBoot3 and integration with Spring Cloud Vault.
Understanding the Basics:
What is Vault:
Spring Cloud Vault provides support to externalize the configurations for client-side applications in a distributed environment.
With HashiCorp’s Vault we have a central place to manage external secret/confidential properties for applications across all environments.
Vault can manage static and dynamic secrets such as username/password for remote applications/resources and provide credentials for external services such as MySQL, PostgreSQL, Apache Cassandra, MongoDB, Consul, AWS and more.
Implementation:
To implement Vault in SpringBoot 3.1.x and spring cloud 2022.0.3 for native-image development, we need to follow the below steps:
A. Add these in pom.xml
for vault:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
for native add the below plugin in POM.xml:
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
B. Add the Vault property details in application.yml file
spring:
config:
import: vault://
profiles:
active: dev
application:
name: client-service
cloud:
vault:
authentication: APPROLE
fail-fast: false
uri: {{vault-uri}}
kv:
enabled: true
backend: {{backend-environment}}
application-name: Platform/client-service/dev
app-role:
role-id: {{role-id}}
secret-id: {{secret-id}}
generic:
enabled: false
C. We need to bind VaultResponse class using annotation @RegisterReflectionForBinding. It Indicates that the VaultResponse class require some reflection hints for binding or reflection-based serialization purposes.
@RegisterReflectionForBinding({VaultResponse.class})
D. In case you have any other error of reflection for any other class or interface. Create a Class which implements RuntimeHintsRegistrar. These runtime hints are added so that reflection and proxy classes can be specified upfront to the native compiler at the build time, else the build will fail.
public class VaultRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(org.springframework.aot.hint.RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(TypeReference.of("org.springframework.cloud.vault.config.VaultHealthIndicator"), builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
}
}
E. Once the RuntimeHint class is ready (point D), we need to let Spring context aware that this class is present and has to be included during the build phase.
For the same below import is done on the SpringBoot main application class.
@ImportRuntimeHints(VaultRuntimeHints.class)
This is all the work you need to do. Now you can build the application as native and run it.
All done!! Spring Cloud Vault is now working as natively.
Github Link:
https://github.com/LetsCodeKnownSense/VaultSpringBoot3Native
Good explanation of rare and new topic. Thanks for it.