New unit test format

This commit is contained in:
Nick
2019-08-30 21:11:18 +01:00
parent db85c8f275
commit 6cd385e4c0
19972 changed files with 1626600 additions and 0 deletions
@@ -0,0 +1,29 @@
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
## Extra
/vault-data/
*.log
@@ -0,0 +1,3 @@
### Relevant Articles:
- [An Intro to Spring Cloud Vault](https://www.baeldung.com/spring-cloud-vault)
@@ -0,0 +1,20 @@
--
-- Sample schema for testing vault database secrets
--
create schema fakebank;
use fakebank;
create table account(
id decimal(16,0),
name varchar(30),
branch_id decimal(16,0),
customer_id decimal(16,0),
primary key (id));
--
-- MySQL user that will be used by Vault to create other users on demand
--
create user 'fakebank-admin'@'%' identified by 'Sup&rSecre7!'
grant all privileges on fakebank.* to 'fakebank-admin'@'%' with grant option;
grant create user on *.* to 'fakebank-admin' with grant option;
flush privileges;
+86
View File
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.baeldung.spring.cloud</groupId>
<artifactId>spring-cloud-vault</artifactId>
<name>spring-cloud-vault</name>
<packaging>jar</packaging>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-config-databases</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
</project>
@@ -0,0 +1,6 @@
path "secret/fakebank" {
capabilities = ["read"]
allowed_parameters = {
"api_key" = []
}
}
@@ -0,0 +1,10 @@
package org.baeldung.spring.cloud.vaultsample;
import org.baeldung.spring.cloud.vaultsample.domain.Account;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface AccountRepo extends JpaRepository<Account, Long>{
}
@@ -0,0 +1,27 @@
package org.baeldung.spring.cloud.vaultsample;
import org.baeldung.spring.cloud.vaultsample.domain.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AccountResource {
@Autowired
private AccountRepo repo;
@GetMapping("/account/{id}")
public ResponseEntity<Account> getAccount(@PathVariable("id") Long id) {
Account acc = repo.findById(id).orElse(null);
if ( acc != null ) {
return new ResponseEntity<Account>(acc, HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
}
@@ -0,0 +1,37 @@
/**
*
*/
package org.baeldung.spring.cloud.vaultsample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Philippe
*
*/
@RestController
public class SecretResource {
@Autowired
Environment env;
@GetMapping("/secret/{key}")
public ResponseEntity<String> readSecret(@PathVariable("key") String key) {
String value = env.getProperty(key);
if ( value != null ) {
return new ResponseEntity<String>(value, HttpStatus.OK);
}
else {
return new ResponseEntity<String>("not found", HttpStatus.NOT_FOUND);
}
}
}
@@ -0,0 +1,12 @@
package org.baeldung.spring.cloud.vaultsample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class VaultSampleApplication {
public static void main(String[] args) {
SpringApplication.run(VaultSampleApplication.class, args);
}
}
@@ -0,0 +1,133 @@
/**
*
*/
package org.baeldung.spring.cloud.vaultsample.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
/**
* @author Philippe
*
*/
@Entity
@Table(name = "account")
public class Account {
@Id
private Long id;
@NotNull
private String name;
private Long branchId;
private Long customerId;
/**
* @return the id
*/
public Long getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the branchId
*/
public Long getBranchId() {
return branchId;
}
/**
* @param branchId the branchId to set
*/
public void setBranchId(Long branchId) {
this.branchId = branchId;
}
/**
* @return the customerId
*/
public Long getCustomerId() {
return customerId;
}
/**
* @param customerId the customerId to set
*/
public void setCustomerId(Long customerId) {
this.customerId = customerId;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((branchId == null) ? 0 : branchId.hashCode());
result = prime * result + ((customerId == null) ? 0 : customerId.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Account other = (Account) obj;
if (branchId == null) {
if (other.branchId != null)
return false;
} else if (!branchId.equals(other.branchId))
return false;
if (customerId == null) {
if (other.customerId != null)
return false;
} else if (!customerId.equals(other.customerId))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
@@ -0,0 +1,11 @@
spring:
application:
name: fakebank
datasource:
url: jdbc:mysql://localhost:3306/fakebank?serverTimezone=GMT-3
hikari:
connection-test-query: select 1
idle-timeout: 5000
max-lifetime: 120000
maximum-pool-size: 5
@@ -0,0 +1,37 @@
spring:
cloud:
vault:
uri: https://localhost:8200
connection-timeout: 5000
read-timeout: 15000
ssl:
trust-store: classpath:/vault.jks
trust-store-password: changeit
generic:
enabled: true
application-name: fakebank
# kv:
# enabled: false
# backend: kv
# application-name: fakebank
#
database:
enabled: true
role: fakebank-accounts-rw
backend: database
username-property: spring.datasource.username
password-property: spring.datasource.password
#
#
@@ -0,0 +1,15 @@
package org.baeldung.spring.cloud.vaultsample;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = VaultSampleApplication.class)
public class SpringContextIntegrationTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}
@@ -0,0 +1,15 @@
package org.baeldung.spring.cloud.vaultsample;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = VaultSampleApplication.class)
public class SpringContextLiveTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}
@@ -0,0 +1,66 @@
package org.baeldung.spring.cloud.vaultsample;
import static org.junit.Assert.assertEquals;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class VaultSampleApplicationLiveTest {
@Autowired
Environment env;
@Autowired
DataSource datasource;
@Test
public void whenGenericBackendEnabled_thenEnvHasAccessToVaultSecrets() {
String fooValue = env.getProperty("foo");
assertEquals("test-bar", fooValue);
}
@Test
public void whenKvBackendEnabled_thenEnvHasAccessToVaultSecrets() {
String fooValue = env.getProperty("foo.versioned");
assertEquals("bar1", fooValue);
}
@Test
public void whenDatabaseBackendEnabled_thenDatasourceUsesVaultCredentials() {
try (Connection c = datasource.getConnection()) {
ResultSet rs = c.createStatement()
.executeQuery("select 1");
rs.next();
Long value = rs.getLong(1);
assertEquals(Long.valueOf(1), value);
} catch (SQLException sex) {
throw new RuntimeException(sex);
}
}
}
@@ -0,0 +1,3 @@
spring.cloud.vault.token=b93d1b0d-15b5-f69e-d311-352a65fa7bc8
logging.level.org.springframework=INFO
@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC+zCCAeOgAwIBAgIJAKoy5OBgOKYwMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
BAMMCWxvY2FsaG9zdDAeFw0xODA4MDkwMTM1MzJaFw0yODA4MDYwMTM1MzJaMBQx
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMXiHqB5dYdxJ1+abSG55gb3NNo3fzNbkjp/tAIl1FUeyCyyP/yERrkUkhFj
4gg/q1YHUO/ftc0PdL/JBaVBTKnzsxgp7hY/dUEkZqXZ649X0UrJIRd13w5N71cL
P1+PjCrqokMVceU18kK7CyaOmiTKYFmt/RTJQLmFQspmJXNSiq7zUvAgyvoY5TzJ
n7MuSobHXq17pnlm+XbnAgDJUt9yR6BC2dFF20iZU4uTXy2VRngfLey3p+6in0TO
jD4cEMJqwgUbjiI8m/hESCketVkq0W0qkkVfWBNzz5qqGHNRbhZBwT7SM0MuXum+
qEY7n7jcQAk5BDb613liVQjQ0tkCAwEAAaNQME4wHQYDVR0OBBYEFHYjQ0/HJgXd
BnqM4jLPjmygfi8fMB8GA1UdIwQYMBaAFHYjQ0/HJgXdBnqM4jLPjmygfi8fMAwG
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABSf++sinLT9dFnC+B6ut5Zp
haTL7PA1/CdmhTdE2vlFPGGw2BD4c/gphBsHKSNHE96irTqFXI/kl6labQpZ5P8G
JORLfaAyl58UT1FayxL4ISzwsp+UrqO60vxkYyLkbEJjuaxIv11oOoFDIp5oBTqe
BVoCfcTjYtTr+IwwlypLPrVTnDNGX5oPIBbTUFvR0t5RaLZgmXLT78ERhWOLINqh
Yi6j7fYaRm/C5IQ8N/TASot7V0SMH2Rt6PrzJb5SLV8r+yozg2BSfU6hZUyKwABR
N3zppKvKzdhlVo9OuSW3x4Tb3V+CVE/8CmTwRfhab9SCmvmaa2FxI+8/2OPVWDU=
-----END CERTIFICATE-----
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAxeIeoHl1h3EnX5ptIbnmBvc02jd/M1uSOn+0AiXUVR7ILLI/
/IRGuRSSEWPiCD+rVgdQ79+1zQ90v8kFpUFMqfOzGCnuFj91QSRmpdnrj1fRSskh
F3XfDk3vVws/X4+MKuqiQxVx5TXyQrsLJo6aJMpgWa39FMlAuYVCymYlc1KKrvNS
8CDK+hjlPMmfsy5KhsderXumeWb5ducCAMlS33JHoELZ0UXbSJlTi5NfLZVGeB8t
7Len7qKfRM6MPhwQwmrCBRuOIjyb+ERIKR61WSrRbSqSRV9YE3PPmqoYc1FuFkHB
PtIzQy5e6b6oRjufuNxACTkENvrXeWJVCNDS2QIDAQABAoIBACEyB5VACtlHwCUn
kLshplbwzWr1+F6zM9qgZaAenHoTCd2FoXpI7lxJ+R71tItRsvphi9BRpPvbZehu
XoYUaDnyac7Z6djNmGvvIVEdN4j6YF+9UdHPsjWCGW5uspjjSc5BQisiw9KBtDxB
iGNVdMJLONKSf2wnPrZgho3RiOLJX/poPyGTkMHuhBVvo4oy7Ax3XalaAcufgqwm
YBQJ1Tka+33EUiLkxzJTXxNbIAI2scP8jhGn6mokS0V4gZPxJKUZEyydXRWwi6ex
ua/7q76ELJS5b+xKRYfGsvavFDx8R+LqX8oegALD33ki3rm1MQW7GmikRL98+EVW
Q9mQsqECgYEA/IrP8vycbJOgn1vriNItFcZtczSBlrXCRF0up2cqKMs9c+T5i51x
ZKXK5lo3DfMT+YDM+iiGZ9+vM0UA2VxbFD3XV9mQDBaNC+Duknqxx+OLmWva9YwR
nMaevqVV9LCn+GgUcK+IygEnpzpdP4q8YcXAfGAnZgnihN/AUYAaB70CgYEAyJe4
yO0S9gAH5aoDdooL0YXrH/Dzd+fAgNsawLhoOltcoZqZFWeAllM0GsrCpfTRltuy
dn9ca3YK0GlWl7h5rDle1HO3nhp1FcpeG1oxmkeQta3PG66uUuMccTAljCLFrEe3
DguH8+qdjhLk+ZnUB9AVkS79pzdwuEHVljCK600CgYB6mMygkh9B2lzkX9Q0xItc
gcqKXdf3GN9pHq9SVxOxYBDCHUtDirgMeyvHrc4COJneyrc3TcsJzB4aToo9+sbA
SdErdZOnOp9YP+axN1zsw7r2TNSr1UaLjCRuOodC1SuFvMkHdz95iRv946h2+1u+
PyjVeDxIHc5YYOLU7dI1JQKBgQDF5KDBYNm25brkwcCe3nvgXfzjyyN25KUOupn/
DS6Oe/m72Lgz3KOIKleaIvS7IvbunJnIu8dioNb0Wye5kJ5A4WyDrhG1IabnM3l6
BJYw/W9vPSS4y7FhRnuV0wkH4nofh7S5X3jlk02Sj2NkN3Vtq8TLMY++uzwyG4jq
ncM/dQKBgQC+6mA5OfbVN4lRn+zrSiIH5gpvZYPh9wXeTnDWHa13sJsu3e8AQxtk
TfE0W13UV5jhGL8Wvyyxn+doGFTdcZapOlwuoQ6RcgHcVQm2sOl60GAa4idmm0A6
TcgnIOTyVRlNBoWLCfN83BlGz4gcDpnuZZ/0JuguixgLS323hQlLvg==
-----END RSA PRIVATE KEY-----
@@ -0,0 +1,23 @@
/*
* Sample configuration file for tests
*/
// Enable UI
ui = true
// Filesystem storage
storage "file" {
path = "./vault-data"
}
// TCP Listener using a self-signed certificate
listener "tcp" {
address = "127.0.0.1:8200"
tls_cert_file = "./src/test/vault-config/localhost.cert"
tls_key_file = "./src/test/vault-config/localhost.key"
}
// Audit to stdout
@@ -0,0 +1,79 @@
== Vault server bootstrap
1. Run vaul-start in one shell
2. Open another shell and execute the command below:
> vault operator init
Unseal Key 1: Iwvpd4IVofhcmQ2HEIPs5HMUbz4tz6JhqmLZ6+1MhAPx
Unseal Key 2: ANQDXUFGGtLtt6grX25YsdmeKELhM/ioKWzwFukJIe2f
Unseal Key 3: 8MHyzFnOvlwVQzdWYJ3BIN4xPDOn8a4VemZ/Qe5HgurU
Unseal Key 4: ywT9YR9OfxIpA4l1RniNNCvSZWAuNZsAEFRyD7aqFOrp
Unseal Key 5: q1c7M+lnlT72jGLoCH+jjri6KGSBhc5lCzlT0I1R9URU
Initial Root Token: dee7107a-8819-0719-62a3-cea3ea854589
...
== Admin token setup
1. Set the VAULT_TOKEN environment variable with the root token value
export VAULT_TOKEN=d341fdaf-1cf9-936a-3c38-cf5eec94b5c0 (Linux)
set VAULT_TOKEN=d341fdaf-1cf9-936a-3c38-cf5eec94b5c0 (Windows)
2. Create another admin token
>vault token create -display-name=admin
Key Value
--- -----
token 3779c3ca-9f5e-1d8f-3842-efa96d88de43 <=== this is the new root token
token_accessor 2dfa4031-973b-cf88-c749-ee6f520ecaea
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]
3. Create ~/.vault-secret with your root token
4. Unset the VAULT_TOKEN environment variable !
=== Test DB setup (MySQL only, for now)
1. Create test db
2. Create admin account used to create dynamic accounts:
create schema fakebank;
create user 'fakebank-admin'@'%' identified by 'Sup&rSecre7!'
grant all privileges on fakebank.* to 'fakebank-admin'@'%' with grant option;
grant create user on *.* to 'fakebank-admin' with grant option;
flush privileges;
=== Database secret backend setup
> vault secrets enable database
==== Create db configuration
> vault write database/config/mysql-fakebank ^
plugin_name=mysql-legacy-database-plugin ^
connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/fakebank" ^
allowed_roles="*" ^
username="fakebank-admin" ^
password="Sup&rSecre7!"
==== Create roles
> vault write database/roles/fakebank-accounts-ro ^
db_name=mysql-fakebank ^
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON fakebank.* TO '{{name}}'@'%';" ^
default_ttl="1h" ^
max_ttl="24h"
> vault write database/roles/fakebank-accounts-rw ^
db_name=mysql-fakebank ^
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT,INSERT,UPDATE ON fakebank.* TO '{{name}}'@'%';" ^
default_ttl="5m" ^
max_ttl="30m"
=== Get credentials
> vault read database/creds/fakebank-accounts-rw
@@ -0,0 +1,5 @@
@echo off
echo Setting environment variables to access local vault..
set VAULT_ADDR=https://localhost:8200
set VAULT_CACERT=%~dp0%/src/test/vault-config/localhost.cert
rem set VAULT_TLS_SERVER_NAME=localhost
@@ -0,0 +1,6 @@
#!/bin/bash
echo Setting environment variables to access local vault..
SCRIPTPATH=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )
export VAULT_ADDR=https://localhost:8200
export VAULT_CACERT=$SCRIPTPATH/src/test/vault-config/localhost.cert
export VAULT_TLS_SERVER_NAME=localhost
@@ -0,0 +1,3 @@
echo Starting vault server...
pushd %~dp0%
vault server -config %~dp0%/src/test/vault-config/vault-test.hcl
@@ -0,0 +1,5 @@
#!/bin/bash
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
pushd $SCRIPTPATH
echo Starting vault server...
vault server -config $SCRIPTPATH/src/test/vault-config/vault-test.hcl
@@ -0,0 +1,7 @@
call %~dp0%/vault-env.bat
vault operator unseal Iwvpd4IVofhcmQ2HEIPs5HMUbz4tz6JhqmLZ6+1MhAPx
vault operator unseal ANQDXUFGGtLtt6grX25YsdmeKELhM/ioKWzwFukJIe2f
vault operator unseal 8MHyzFnOvlwVQzdWYJ3BIN4xPDOn8a4VemZ/Qe5HgurU
@@ -0,0 +1,8 @@
#!/bin/bash
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
. $SCRIPTPATH/vault-env.sh
# Please replace the unseal keys below for your own
vault operator unseal OfCseaSZzjTZmrxhfx+5clKobwLGCNiJdAlfixSG9E3o
vault operator unseal iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT
vault operator unseal K0TleK3OYUvWFF+uIDsQuf5a+/gkv1PtZ3O47ornzRoF