Spring Boot Vault Integration Testing with Testcontainers | Guide


Explanation:

  • Spring Boot: Represents the Spring Boot application.
  • Testcontainers: This section represents the Testcontainers framework that spins up the Vault container for integration testing.
  • Vault Container: Represents the Vault container that is managed by Testcontainers.
  • Vault: Represents HashiCorp Vault itself.

To integrate Spring Boot with HashiCorp Vault using Testcontainers for end-to-end testing, we need to follow these steps:

Docker Setup 

Install Docker: Download and install Docker from Docker's official website.
  • Windows/macOS: Install and run Docker Desktop.
  • Linux: Install Docker Engine using your package manager.
Verify Installation:
Run docker --version to confirm Docker is installed.
Start Docker:
  • Windows/macOS: Launch Docker Desktop and ensure it’s running.
  • Linux: Start Docker with sudo systemctl start docker.


Add Dependencies

Add the required dependencies in your pom.xml for Spring Boot, HashiCorp Vault, and Testcontainers.

<properties>
    <java.version>17</java.version>
    <spring-cloud.version>2024.0.0</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-vault-config</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-testcontainers</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>junit-jupiter</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>vault</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>


Spring Boot Configuration

Set up your application.yml or application.properties for Vault integration.
spring:
  cloud:
    vault:
      uri: http://localhost:8200
      authentication: TOKEN
      token: <your_vault_token>
      kv:
        enabled: true
        backend: secret
        default-context: application

 

Testcontainers Setup

Create a test class for the Vault container setup. You can use Testcontainers to spin up a Vault instance for integration testing.

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.testcontainers.containers.VaultContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@ExtendWith(SpringExtension.class)
@Testcontainers
@SpringBootTest
public class VaultIntegrationTest {

    @Container
    public static VaultContainer vault = new VaultContainer("vault:latest")
            .withExposedPorts(8200)
            .withVaultToken("myroot");

    @Autowired
    private YourService yourService;

    @BeforeAll
    static void setUp() {
        // Initialize Vault with secrets
        vault.execInContainer("vault", "kv", "put", "secret/myapp", "key=value");
    }

    @Test
    void testVaultIntegration() {
        // Your test code interacting with the Vault service
        String secret = yourService.getSecretFromVault();
        assertNotNull(secret);
        assertEquals("value", secret);
    }
}
  • The @Container annotation spins up the Vault container before tests run.
  • In the setUp() method, we initialize the Vault container and add some secrets for testing.
  • The @SpringBootTest annotation loads the Spring context for the test.


Service Class

You need to create a service class that interacts with Vault. You can use Spring's VaultTemplate or the @Value annotation to inject secrets from Vault.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class YourService {

    @Value("${secret.myapp.key}")
    private String secretKey;

    public String getSecretFromVault() {
        return secretKey;
    }
}

Run the Test

With the setup complete, you can run the tests. The Vault container will start up, and Spring Boot will load the secrets from the Vault instance for the test.
./mvnw test

This setup ensures that you have an end-to-end test for your Spring Boot application that interacts with HashiCorp Vault, running inside a Testcontainers-managed container.

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete