diff --git a/pom.xml b/pom.xml
index 95c5e23e0a..b10cab6b1a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1106,6 +1106,7 @@
spring-remoting
spring-reactor
spring-vertx
+ spring-vault
spring-jinq
spring-rest-embedded-tomcat
testing-modules/testing
diff --git a/spring-vault/pom.xml b/spring-vault/pom.xml
new file mode 100644
index 0000000000..31616cdb16
--- /dev/null
+++ b/spring-vault/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ spring-vault
+ 0.0.1-SNAPSHOT
+ jar
+ spring-vault
+ Spring Vault sample project
+
+
+ parent-boot-2
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../parent-boot-2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.vault
+ spring-vault-core
+ ${spring.vault.core.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ **/*IntegrationTest.java
+
+
+
+
+
+
+
+ UTF-8
+ 2.0.1.RELEASE
+
+
diff --git a/spring-vault/src/main/java/org/baeldung/springvault/Credentials.java b/spring-vault/src/main/java/org/baeldung/springvault/Credentials.java
new file mode 100644
index 0000000000..f90ab66a4e
--- /dev/null
+++ b/spring-vault/src/main/java/org/baeldung/springvault/Credentials.java
@@ -0,0 +1,30 @@
+package org.baeldung.springvault;
+
+public class Credentials {
+
+ private String username;
+ private String password;
+
+ public Credentials() {
+
+ }
+
+ public Credentials(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public String toString() {
+ return "Credential [username=" + username + ", password=" + password + "]";
+ }
+
+}
diff --git a/spring-vault/src/main/java/org/baeldung/springvault/CredentialsService.java b/spring-vault/src/main/java/org/baeldung/springvault/CredentialsService.java
new file mode 100644
index 0000000000..87c24bd947
--- /dev/null
+++ b/spring-vault/src/main/java/org/baeldung/springvault/CredentialsService.java
@@ -0,0 +1,50 @@
+package org.baeldung.springvault;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.vault.authentication.TokenAuthentication;
+import org.springframework.vault.client.VaultEndpoint;
+import org.springframework.vault.core.VaultTemplate;
+import org.springframework.vault.core.env.VaultPropertySource;
+import org.springframework.vault.support.VaultResponse;
+import org.springframework.vault.support.VaultResponseSupport;
+
+/**
+ * Sample service to demonstrate storing and retrieval of secrets.
+ *
+ * NOTE: We need to configure Vault and provide the Vault uri in the properties file.
+ *
+ */
+@Service
+public class CredentialsService {
+
+ @Autowired
+ private VaultTemplate vaultTemplate;
+
+ /**
+ * To Secure Credentials
+ * @param credentials
+ * @return VaultResponse
+ * @throws URISyntaxException
+ */
+ public void secureCredentials(Credentials credentials) throws URISyntaxException {
+
+ vaultTemplate.write("credentials/myapp", credentials);
+ }
+
+ /**
+ * To Retrieve Credentials
+ * @return Credentials
+ * @throws URISyntaxException
+ */
+ public Credentials accessCredentials() throws URISyntaxException {
+
+ VaultResponseSupport response = vaultTemplate.read("credentials/myapp", Credentials.class);
+ return response.getData();
+ }
+
+}
diff --git a/spring-vault/src/main/java/org/baeldung/springvault/SpringVaultApplication.java b/spring-vault/src/main/java/org/baeldung/springvault/SpringVaultApplication.java
new file mode 100644
index 0000000000..916a809be5
--- /dev/null
+++ b/spring-vault/src/main/java/org/baeldung/springvault/SpringVaultApplication.java
@@ -0,0 +1,17 @@
+package org.baeldung.springvault;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Sample application to demonstrate basics of Spring Vault
+ *
+ */
+@SpringBootApplication
+public class SpringVaultApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringVaultApplication.class, args);
+ }
+
+}
diff --git a/spring-vault/src/main/java/org/baeldung/springvault/VaultConfig.java b/spring-vault/src/main/java/org/baeldung/springvault/VaultConfig.java
new file mode 100644
index 0000000000..106a1a3d42
--- /dev/null
+++ b/spring-vault/src/main/java/org/baeldung/springvault/VaultConfig.java
@@ -0,0 +1,26 @@
+package org.baeldung.springvault;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.vault.authentication.ClientAuthentication;
+import org.springframework.vault.authentication.TokenAuthentication;
+import org.springframework.vault.client.VaultEndpoint;
+import org.springframework.vault.config.AbstractVaultConfiguration;
+
+/**
+ * Example class to configure Vault beans using AbstractVaultConfiguration
+ *
+ */
+@Configuration
+public class VaultConfig extends AbstractVaultConfiguration {
+
+ @Override
+ public ClientAuthentication clientAuthentication() {
+ return new TokenAuthentication("00000000-0000-0000-0000-000000000000");
+ }
+
+ @Override
+ public VaultEndpoint vaultEndpoint() {
+ return VaultEndpoint.create("host", 8020);
+ }
+
+}
diff --git a/spring-vault/src/main/java/org/baeldung/springvault/VaultEnvironmentConfig.java b/spring-vault/src/main/java/org/baeldung/springvault/VaultEnvironmentConfig.java
new file mode 100644
index 0000000000..6c796bc718
--- /dev/null
+++ b/spring-vault/src/main/java/org/baeldung/springvault/VaultEnvironmentConfig.java
@@ -0,0 +1,21 @@
+package org.baeldung.springvault;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.vault.authentication.ClientAuthentication;
+import org.springframework.vault.authentication.TokenAuthentication;
+import org.springframework.vault.client.VaultEndpoint;
+import org.springframework.vault.config.AbstractVaultConfiguration;
+import org.springframework.vault.config.EnvironmentVaultConfiguration;
+
+/**
+ * Example class to configure Vault beans using EnvironmentVaultConfiguration
+ *
+ */
+@Configuration
+@PropertySource(value = { "vault-config.properties" })
+@Import(value = EnvironmentVaultConfiguration.class)
+public class VaultEnvironmentConfig {
+
+}
diff --git a/spring-vault/src/main/resources/vault-config.properties b/spring-vault/src/main/resources/vault-config.properties
new file mode 100644
index 0000000000..68a080ebe8
--- /dev/null
+++ b/spring-vault/src/main/resources/vault-config.properties
@@ -0,0 +1,2 @@
+vault.uri=https://localhost:8200
+vault.token=00000000-0000-0000-0000-000000000000
\ No newline at end of file
diff --git a/spring-vault/src/test/java/org/baeldung/springvault/VaultInitializer.java b/spring-vault/src/test/java/org/baeldung/springvault/VaultInitializer.java
new file mode 100644
index 0000000000..c7db5eb199
--- /dev/null
+++ b/spring-vault/src/test/java/org/baeldung/springvault/VaultInitializer.java
@@ -0,0 +1,113 @@
+package org.baeldung.springvault;
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Map;
+
+/**
+ *
+ * This is a test class to initialize Vault.
+ */
+public class VaultInitializer implements Closeable {
+
+ private static final String UNSEAL_KEY = "Unseal Key:";
+ private static final String ROOT_TOKEN = "Root Token:";
+
+ private Process vaultProcess;
+ private String unSealKey;
+ private String rootToken;
+
+ public String getRootToken() {
+ return rootToken;
+ }
+
+ public String getUnSealKey() {
+ return unSealKey;
+ }
+
+ public static final VaultInitializer initializeValut() {
+ VaultInitializer vaultProcess = new VaultInitializer();
+ vaultProcess.start();
+ // Secrets is by default enabled.
+ vaultProcess.enableSecrets();
+ return vaultProcess;
+ }
+
+ @SuppressWarnings("unused")
+ private void enableSecrets() {
+ System.out.println("Enabling Secrets at path credentials/myapp...");
+ ProcessBuilder pb = new ProcessBuilder("vault", "secrets", "enable", "-path=credentials/myapp", "kv");
+ Map map = pb.environment();
+ map.put("VAULT_ADDR", "http://127.0.0.1:8200");
+ try {
+ Process p = pb.inheritIO()
+ .start();
+ p.waitFor();
+ } catch (IOException e) {
+ System.out.println("unable to enableSecrets" + e);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void start() {
+ System.out.println("starting vault");
+ // This starts the vault server.
+ ProcessBuilder pb = new ProcessBuilder("vault", "server", "-dev");
+
+ try {
+ vaultProcess = pb.start();
+ // wait for initialization to complete.
+ Thread.sleep(5000);
+ } catch (IOException e) {
+ System.out.println("unable to start vault in new process" + e);
+ } catch (InterruptedException e) {
+ System.out.println("Thread interrupted " + e);
+ }
+ extractUnsealKeyAndToken();
+ }
+
+ /**
+ * To get the root token which is generated every time server is initialized.
+ */
+ private void extractUnsealKeyAndToken() {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(vaultProcess.getInputStream()));
+ StringBuilder builder = new StringBuilder();
+ String line = null;
+ boolean tokenExtracted = false;
+ try {
+ while ((line = reader.readLine()) != null) {
+ builder.append(line);
+ builder.append(System.getProperty("line.separator"));
+ if (line.contains(UNSEAL_KEY)) {
+ String tmp = line.replace(UNSEAL_KEY, "");
+ unSealKey = tmp.trim();
+ } else if (line.contains(ROOT_TOKEN)) {
+ String tmp = line.replace(ROOT_TOKEN, "");
+ rootToken = tmp.trim();
+ tokenExtracted = true;
+ }
+ if (tokenExtracted)
+ break;
+ System.out.println(line);
+ }
+ } catch (IOException e) {
+ System.out.println("unable to read vault output" + e);
+ }
+
+ String result = builder.toString();
+
+ System.out.println("Unseal Key {}" + unSealKey);
+ System.out.println("Root Token {}" + rootToken);
+ System.out.println(result);
+ }
+
+ @Override
+ public void close() throws IOException {
+
+ System.out.println("stoping vault");
+ vaultProcess.destroy();
+ }
+}
diff --git a/spring-vault/src/test/java/org/baeldung/springvault/VaultIntegrationTest.java b/spring-vault/src/test/java/org/baeldung/springvault/VaultIntegrationTest.java
new file mode 100644
index 0000000000..75c700ee26
--- /dev/null
+++ b/spring-vault/src/test/java/org/baeldung/springvault/VaultIntegrationTest.java
@@ -0,0 +1,80 @@
+package org.baeldung.springvault;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.annotation.Order;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.annotation.DirtiesContext.ClassMode;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+import org.springframework.vault.authentication.TokenAuthentication;
+import org.springframework.vault.client.VaultEndpoint;
+import org.springframework.vault.core.VaultTemplate;
+import org.springframework.vault.support.VaultResponse;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = CredentialsService.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ContextConfiguration(classes = VaultTestConfiguration.class, loader = AnnotationConfigContextLoader.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
+public class VaultIntegrationTest {
+
+ @Autowired
+ private CredentialsService credentialsService;
+
+ /**
+ * Test to secure credentials.
+ *
+ * @throws URISyntaxException
+ */
+ @Test
+ public void givenCredentials_whenSecureCredentials_thenCredentialsSecured() throws URISyntaxException {
+ try {
+ // Given
+ Credentials credentials = new Credentials("username", "password");
+
+ // When
+ credentialsService.secureCredentials(credentials);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Test to access credentials
+ * @throws URISyntaxException
+ */
+ @Test
+ public void whenAccessCredentials_thenCredentialsRetrieved() throws URISyntaxException {
+
+ // Given
+ Credentials credentials = credentialsService.accessCredentials();
+
+ // Then
+ assertNotNull(credentials);
+ assertEquals("username", credentials.getUsername());
+ assertEquals("password", credentials.getPassword());
+ }
+
+}
diff --git a/spring-vault/src/test/java/org/baeldung/springvault/VaultTestConfiguration.java b/spring-vault/src/test/java/org/baeldung/springvault/VaultTestConfiguration.java
new file mode 100644
index 0000000000..09a1445788
--- /dev/null
+++ b/spring-vault/src/test/java/org/baeldung/springvault/VaultTestConfiguration.java
@@ -0,0 +1,29 @@
+package org.baeldung.springvault;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.vault.authentication.TokenAuthentication;
+import org.springframework.vault.client.VaultEndpoint;
+import org.springframework.vault.core.VaultTemplate;
+
+@Configuration
+public class VaultTestConfiguration {
+
+ @Bean
+ public VaultInitializer vaultInitializer() {
+ VaultInitializer vaultInitializer = VaultInitializer.initializeValut();
+ return vaultInitializer;
+ }
+
+ @Bean
+ public VaultTemplate vaultTemplate() throws URISyntaxException {
+
+ VaultInitializer vaultInitializer = vaultInitializer();
+ VaultTemplate vaultTemplate = new VaultTemplate(VaultEndpoint.from(new URI("http://localhost:8200")), new TokenAuthentication(vaultInitializer.getRootToken()));
+ return vaultTemplate;
+
+ }
+}