36 Commits

Author SHA1 Message Date
1072e9b4a9 split VaultConnector interface into clients per module
All checks were successful
CI / build (11) (push) Successful in 33s
CI / build (17) (push) Successful in 31s
CI / build (true, 21) (push) Successful in 25s
The connector interface has grown quite big and does not even cover all
potential APIs. We now extract functionality into submodules and group
them to handle each area in separate interfaces. Provide fluent access,
strip prefixes from methods and preserve a 1:1 migration path.

Examples:

* connector.unseal() => connector.sys().unseal()
* connector.readSecretVersion() => connector.kv2().readVersion()
* connector.createToken() => connector.token().create()
* connector.lookupAppRole() => connector.appRole().lookup()
* connector.transitHash() => connector.transit().hash()
2025-09-02 15:35:18 +02:00
e96ece3385 build: update maven-wrapper to 3.3.3
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 49s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m6s
CI / build-with-it (21, 1.2.0) (push) Successful in 49s
CI / build-with-it (17, 1.2.0) (push) Successful in 48s
CI / build-with-it (17, 1.20.0) (push) Successful in 1m5s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 59s
2025-09-02 13:27:29 +02:00
41eeae6687 refactor: extract API paths into a utility class (#108)
Some checks failed
CI / build-with-it (11, 1.2.0) (push) Successful in 50s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m8s
CI / build-with-it (17, 1.2.0) (push) Successful in 46s
CI / build-with-it (true, 21, 1.20.0) (push) Has been cancelled
CI / build-with-it (17, 1.20.0) (push) Has been cancelled
CI / build-with-it (21, 1.2.0) (push) Has been cancelled
Extract some static String constants from HTTPVaultConnector, which is
quite long already, into an internal utility class VaultApiPath.
We just reorganize some constants that should not change any behavior.
2025-08-30 09:53:46 +02:00
bac06c5d19 fix: prevent potential off-by-1 error in internal mapOf() helper (#107)
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 43s
CI / build-with-it (11, 1.20.0) (push) Successful in 53s
CI / build-with-it (17, 1.2.0) (push) Successful in 40s
CI / build-with-it (17, 1.20.0) (push) Successful in 52s
CI / build-with-it (21, 1.2.0) (push) Successful in 41s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 45s
2025-08-30 09:41:09 +02:00
e30a3bd93a build: update sonar-maven-plugin to 5.2.0.4988
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 44s
CI / build-with-it (11, 1.20.0) (push) Successful in 51s
CI / build-with-it (17, 1.2.0) (push) Successful in 40s
CI / build-with-it (17, 1.20.0) (push) Successful in 49s
CI / build-with-it (21, 1.2.0) (push) Successful in 39s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 46s
2025-08-30 09:11:21 +02:00
8447b572b4 build: update maven-javadoc-plugin to 3.11.3 2025-08-30 09:10:26 +02:00
a95b05ba0e build: update GitHub actions 2025-08-30 09:08:30 +02:00
29517b9d78 deps: update jackson to 2.20.0 (#106)
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 47s
CI / build-with-it (11, 1.20.0) (push) Successful in 54s
CI / build-with-it (17, 1.2.0) (push) Successful in 43s
CI / build-with-it (17, 1.20.0) (push) Successful in 53s
CI / build-with-it (21, 1.2.0) (push) Successful in 44s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 51s
2025-08-29 17:36:24 +02:00
1536c23cf0 test(deps): update mockito-core to 5.19.0
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 47s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m0s
CI / build-with-it (17, 1.2.0) (push) Successful in 46s
CI / build-with-it (17, 1.20.0) (push) Successful in 57s
CI / build-with-it (21, 1.2.0) (push) Successful in 46s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 54s
2025-08-16 10:23:36 +02:00
a7a435b420 test(deps): update junit-jupiter to 5.13.3
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 57s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m13s
CI / build-with-it (17, 1.2.0) (push) Successful in 52s
CI / build-with-it (17, 1.20.0) (push) Successful in 1m11s
CI / build-with-it (21, 1.2.0) (push) Successful in 50s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 1m4s
2025-07-20 15:47:32 +02:00
d1b8b12ffe test(deps): update commons-io to 2.20.0 2025-07-20 15:47:31 +02:00
27c94870d3 deps: update jackson to 2.19.2 (#105) 2025-07-20 15:47:30 +02:00
12aee10741 prepare for next development iteration
All checks were successful
CI / build (11) (push) Successful in 38s
CI / build (17) (push) Successful in 39s
CI / build (true, 21) (push) Successful in 36s
CI / build-with-it (11, 1.2.0) (push) Successful in 54s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m8s
CI / build-with-it (17, 1.2.0) (push) Successful in 57s
CI / build-with-it (17, 1.20.0) (push) Successful in 1m10s
CI / build-with-it (21, 1.2.0) (push) Successful in 1m10s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 1m13s
2025-07-16 18:36:24 +02:00
1803728256 prepare release v1.5.2
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 56s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m11s
CI / build-with-it (17, 1.2.0) (push) Successful in 58s
CI / build-with-it (17, 1.20.0) (push) Successful in 1m10s
CI / build-with-it (21, 1.2.0) (push) Successful in 54s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 1m2s
2025-07-16 18:22:35 +02:00
9e7d8f50d3 build: update maven to 3.9.11
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 1m1s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m12s
CI / build-with-it (17, 1.2.0) (push) Successful in 56s
CI / build-with-it (17, 1.20.0) (push) Successful in 1m8s
CI / build-with-it (21, 1.2.0) (push) Successful in 57s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 1m9s
2025-07-16 18:09:25 +02:00
08886a0c7c build: update maven-gpg-plugin to 3.2.8 2025-07-16 18:08:19 +02:00
eebe3f0ef6 build: update maven-enforcer-plugin to 3.6.1 2025-07-16 18:08:05 +02:00
5b9f1392d3 build: restore argLine to fix code coverage
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 49s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m6s
CI / build-with-it (17, 1.2.0) (push) Successful in 44s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 1m26s
CI / build-with-it (17, 1.20.0) (push) Successful in 1m8s
CI / build-with-it (21, 1.2.0) (push) Successful in 51s
Partially reverts da4fffc823
2025-07-15 08:41:46 +02:00
da4fffc823 build remove unused test module access flags
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 40s
CI / build-with-it (11, 1.20.0) (push) Successful in 51s
CI / build-with-it (17, 1.2.0) (push) Successful in 39s
CI / build-with-it (17, 1.20.0) (push) Successful in 50s
CI / build-with-it (21, 1.2.0) (push) Successful in 41s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 48s
Remove redundant module opens directives and argLine property
inheritance, keeping only essential module access config for tests.
2025-07-13 18:38:47 +02:00
91276e1615 test: autoformat test code
All checks were successful
CI / build (11) (push) Successful in 34s
CI / build (17) (push) Successful in 32s
CI / build (true, 21) (push) Successful in 28s
CI / build-with-it (11, 1.2.0) (push) Successful in 50s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m7s
CI / build-with-it (17, 1.2.0) (push) Successful in 45s
CI / build-with-it (17, 1.20.0) (push) Successful in 1m7s
CI / build-with-it (21, 1.2.0) (push) Successful in 48s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 59s
2025-07-13 18:19:56 +02:00
6d2313289c test: use Files.writeString() for config creation 2025-07-13 18:19:45 +02:00
bcbb3a0926 test: use assertDoesNotThrow instead of try-catch-fail for createFull() 2025-07-13 18:17:48 +02:00
f03c05bd5b fix: use Long for numeric TTL fields (#103) (#104)
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 55s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m8s
CI / build-with-it (17, 1.2.0) (push) Successful in 43s
CI / build-with-it (17, 1.20.0) (push) Successful in 1m3s
CI / build-with-it (21, 1.2.0) (push) Successful in 47s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 53s
Mapping these fields as Integer limits the possible maximum TTL value to
roughly 68 years. This may or may not be a reasonable value, but is
technically a valid number in the JSON response. Convert all TTL-related
fields to Long, so we can map such values.
2025-07-01 20:05:05 +02:00
afdad92ae6 test: run IT against Vault 1.20.0 (#102)
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 59s
CI / build-with-it (11, 1.20.0) (push) Successful in 1m7s
CI / build-with-it (17, 1.2.0) (push) Successful in 56s
CI / build-with-it (17, 1.20.0) (push) Successful in 1m5s
CI / build-with-it (21, 1.2.0) (push) Successful in 54s
CI / build-with-it (true, 21, 1.20.0) (push) Successful in 1m0s
2025-06-26 18:17:23 +02:00
9fa360393d deps: update build and test dependencies 2025-06-26 18:12:42 +02:00
d28c189ec2 deps: update jackson to 2.19.1 (#101)
All checks were successful
CI / build-with-it (21, 1.2.0) (push) Successful in 1m1s
CI / build-with-it (true, 21, 1.19.5) (push) Successful in 1m9s
CI / build-with-it (11, 1.2.0) (push) Successful in 1m1s
CI / build-with-it (11, 1.19.5) (push) Successful in 1m7s
CI / build-with-it (17, 1.2.0) (push) Successful in 1m3s
CI / build-with-it (17, 1.19.5) (push) Successful in 1m11s
2025-06-20 20:28:52 +02:00
46fffcc711 prepare for next development iteration
All checks were successful
CI / build (11) (push) Successful in 39s
CI / build (17) (push) Successful in 39s
CI / build (true, 21) (push) Successful in 29s
CI / build-with-it (11, 1.2.0) (push) Successful in 57s
CI / build-with-it (11, 1.19.5) (push) Successful in 1m6s
CI / build-with-it (17, 1.19.5) (push) Successful in 1m3s
CI / build-with-it (17, 1.2.0) (push) Successful in 57s
CI / build-with-it (21, 1.2.0) (push) Successful in 51s
CI / build-with-it (true, 21, 1.19.5) (push) Successful in 1m1s
2025-06-02 16:59:30 +02:00
31d8f9b0aa prepare release v1.5.1
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 59s
CI / build-with-it (11, 1.19.5) (push) Successful in 1m8s
CI / build-with-it (17, 1.19.5) (push) Successful in 1m9s
CI / build-with-it (17, 1.2.0) (push) Successful in 1m2s
CI / build-with-it (21, 1.2.0) (push) Successful in 53s
CI / build-with-it (true, 21, 1.19.5) (push) Successful in 1m0s
2025-06-02 16:59:29 +02:00
505b360343 test: run IT against Vault 1.19.5
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 58s
CI / build-with-it (11, 1.19.5) (push) Successful in 1m6s
CI / build-with-it (17, 1.19.5) (push) Successful in 59s
CI / build-with-it (17, 1.2.0) (push) Successful in 53s
CI / build-with-it (21, 1.2.0) (push) Successful in 50s
CI / build-with-it (true, 21, 1.19.5) (push) Successful in 56s
2025-06-01 18:31:41 +02:00
51ab19cd8a deps: update test dependencies
All checks were successful
CI / build-with-it (11, 1.19.0) (push) Successful in 58s
CI / build-with-it (17, 1.2.0) (push) Successful in 50s
CI / build-with-it (17, 1.19.0) (push) Successful in 57s
CI / build-with-it (21, 1.2.0) (push) Successful in 47s
CI / build-with-it (11, 1.2.0) (push) Successful in 52s
CI / build-with-it (true, 21, 1.19.0) (push) Successful in 53s
2025-05-29 15:49:32 +02:00
Lehel Balázs
c8f396a5df use lookup-self for token check instead of lookup (#98) (#99)
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 54s
CI / build-with-it (11, 1.19.0) (push) Successful in 1m0s
CI / build-with-it (17, 1.2.0) (push) Successful in 53s
CI / build-with-it (17, 1.19.0) (push) Successful in 58s
CI / build-with-it (21, 1.2.0) (push) Successful in 48s
CI / build-with-it (true, 21, 1.19.0) (push) Successful in 55s
Using the /lookup-self to retrieve information about the current token
requires less permissions than the general /lookup API and yields the
same results, if accessible.
2025-05-28 18:09:08 +03:00
4bd6039827 deps: update jackson to 2.19.0 (#97)
All checks were successful
CI / build-with-it (11, 1.2.0) (push) Successful in 53s
CI / build-with-it (11, 1.19.0) (push) Successful in 1m0s
CI / build-with-it (17, 1.2.0) (push) Successful in 55s
CI / build-with-it (17, 1.19.0) (push) Successful in 1m0s
CI / build-with-it (21, 1.2.0) (push) Successful in 50s
CI / build-with-it (true, 21, 1.19.0) (push) Successful in 56s
2025-04-27 17:25:23 +02:00
80abbda46f docs: update version and features in README
All checks were successful
CI / build (11) (push) Successful in 39s
CI / build (17) (push) Successful in 39s
CI / build (true, 21) (push) Successful in 34s
CI / build-with-it (11, 1.2.0) (push) Successful in 55s
CI / build-with-it (11, 1.19.0) (push) Successful in 1m2s
CI / build-with-it (17, 1.2.0) (push) Successful in 54s
CI / build-with-it (17, 1.19.0) (push) Successful in 1m0s
CI / build-with-it (21, 1.2.0) (push) Successful in 52s
CI / build-with-it (true, 21, 1.19.0) (push) Successful in 59s
2025-04-24 18:36:36 +02:00
a8e85b88d1 test: use WireMockTest annotation 2025-04-24 18:30:32 +02:00
91baed4fe5 test: update wiremock to 3.13.0 2025-04-24 18:30:04 +02:00
2ea261d36a prepare for next development iteration
All checks were successful
CI / build (11) (push) Successful in 36s
CI / build (17) (push) Successful in 36s
CI / build (true, 21) (push) Successful in 28s
2025-04-13 12:25:18 +02:00
45 changed files with 2696 additions and 2472 deletions

View File

@@ -15,18 +15,18 @@ jobs:
strategy:
matrix:
jdk: [ 11, 17, 21 ]
vault: [ '1.2.0', '1.19.0' ]
vault: [ '1.2.0', '1.20.0' ]
include:
- jdk: 21
vault: '1.19.0'
vault: '1.20.0'
analysis: true
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
java-version: ${{ matrix.jdk }}
distribution: 'temurin'

View File

@@ -21,11 +21,11 @@ jobs:
analysis: true
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
java-version: ${{ matrix.jdk }}
distribution: 'temurin'

View File

@@ -1,2 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

View File

@@ -1,3 +1,35 @@
## unreleased
### Dependencies
* Updated Jackson to 2.20.0 (#106)
### Improvements
* Extract API paths into a utility class (#108)
### Fix
* Prevent potential off-by-1 error in internal `mapOf()` helper (#107)
## 1.5.2 (2025-07-16)
### Dependencies
* Updated Jackson to 2.19.1 (#101)
### Fix
* Use `Long` for numeric TTL fields (#103) (#104)
### Test
* Tested against Vault 1.2 to 1.20 (#102)
## 1.5.1 (2025-06-02)
### Improvements
* Use `lookup-self` for token check instead of `lookup` (#98) (#99)
### Dependencies
* Updated Jackson to 2.19.0 (#97)
## 1.5.0 (2025-04-13)
### Deprecations

View File

@@ -28,10 +28,11 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
* Delete secrets
* Renew/revoke leases
* Raw secret content or JSON decoding
* SQL secret handling
* KV v1 and v2 support
* Database secret handling
* Transit API support
* Connector Factory with builder pattern
* Tested against Vault 1.2 to 1.19
* Tested against Vault 1.2 to 1.20
## Maven Artifact
@@ -39,7 +40,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
<dependency>
<groupId>de.stklcode.jvault</groupId>
<artifactId>jvault-connector</artifactId>
<version>1.4.0</version>
<version>1.5.2</version>
</dependency>
```
@@ -108,11 +109,11 @@ Token token = Token.builder()
.withDisplayName("new test token")
.withPolicies("pol1", "pol2")
.build();
vault.createToken(token);
vault.token().create(token);
// Create AppRole credentials
vault.createAppRole("testrole", policyList);
AppRoleSecretResponse secret = vault.createAppRoleSecret("testrole");
vault.appRole().create("testrole", policyList);
AppRoleSecretResponse secret = vault.appRole().createSecret("testrole");
```
## Links

493
mvnw vendored
View File

@@ -19,314 +19,277 @@
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.3.2
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
# Apache Maven Wrapper startup batch script, version 3.3.3
#
# Optional ENV vars
# -----------------
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ]; then
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
if [ -f /usr/local/etc/mavenrc ]; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ]; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ]; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false
darwin=false
mingw=false
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true ;;
Darwin*)
darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME="$(/usr/libexec/java_home)"
export JAVA_HOME
else
JAVA_HOME="/Library/Java/Home"
export JAVA_HOME
fi
fi
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
if [ -z "$JAVA_HOME" ]; then
if [ -r /etc/gentoo-release ]; then
JAVA_HOME=$(java-config --jre-home)
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin; then
[ -n "$JAVA_HOME" ] \
&& JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
[ -n "$CLASSPATH" ] \
&& CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw; then
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] \
&& JAVA_HOME="$(
cd "$JAVA_HOME" || (
echo "cannot cd into $JAVA_HOME." >&2
exit 1
)
pwd
)"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="$(which javac)"
if [ -n "$javaExecutable" ] && ! [ "$(expr "$javaExecutable" : '\([^ ]*\)')" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=$(which readlink)
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
if $darwin; then
javaHome="$(dirname "$javaExecutable")"
javaExecutable="$(cd "$javaHome" && pwd -P)/javac"
else
javaExecutable="$(readlink -f "$javaExecutable")"
fi
javaHome="$(dirname "$javaExecutable")"
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ]; then
if [ -n "$JAVA_HOME" ]; then
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
if [ -n "${JAVA_HOME-}" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
\unset -f command 2>/dev/null
\command -v java
)"
fi
fi
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
if [ ! -x "$JAVACMD" ]; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ]; then
echo "Warning: JAVA_HOME environment variable is not set." >&2
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]; then
echo "Path not specified to find_maven_basedir" >&2
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ]; do
if [ -d "$wdir"/.mvn ]; then
basedir=$wdir
break
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=$(
cd "$wdir/.." || exit 1
pwd
)
fi
# end of workaround
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf '%s' "$(
cd "$basedir" || exit 1
pwd
)"
printf %x\\n $h
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
# Remove \r in case we run on Windows within Git Bash
# and check out the repository with auto CRLF management
# enabled. Otherwise, we may read lines that are delimited with
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
# splitting rules.
tr -s '\r\n' ' ' <"$1"
fi
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
log() {
if [ "$MVNW_VERBOSE" = true ]; then
printf '%s\n' "$1"
fi
}
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
if [ -z "$BASE_DIR" ]; then
die() {
printf %s\\n "$1" >&2
exit 1
fi
}
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
export MAVEN_PROJECTBASEDIR
log "$MAVEN_PROJECTBASEDIR"
trim() {
# MWRAPPER-139:
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
# Needed for removing poorly interpreted newline sequences when running in more
# exotic environments such as mingw bash on Windows.
printf "%s" "${1}" | tr -d '[:space:]'
}
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
if [ -r "$wrapperJarPath" ]; then
log "Found $wrapperJarPath"
else
log "Couldn't find $wrapperJarPath, downloading it ..."
scriptDir="$(dirname "$0")"
scriptName="$(basename "$0")"
if [ -n "$MVNW_REPOURL" ]; then
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
else
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
fi
while IFS="=" read -r key value; do
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
safeValue=$(echo "$value" | tr -d '\r')
case "$key" in wrapperUrl)
wrapperUrl="$safeValue"
break
;;
esac
done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
log "Downloading from: $wrapperUrl"
if $cygwin; then
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
fi
if command -v wget >/dev/null; then
log "Found wget ... using wget"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl >/dev/null; then
log "Found curl ... using curl"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
else
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
fi
else
log "Falling back to using Java to download"
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaSource=$(cygpath --path --windows "$javaSource")
javaClass=$(cygpath --path --windows "$javaClass")
fi
if [ -e "$javaSource" ]; then
if [ ! -e "$javaClass" ]; then
log " - Compiling MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/javac" "$javaSource")
fi
if [ -e "$javaClass" ]; then
log " - Running MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
wrapperSha256Sum=""
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "$key" in wrapperSha256Sum)
wrapperSha256Sum=$value
break
case "${key-}" in
distributionUrl) distributionUrl=$(trim "${value-}") ;;
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
esac
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
if [ -n "$wrapperSha256Sum" ]; then
wrapperSha256Result=false
if command -v sha256sum >/dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c >/dev/null 2>&1; then
wrapperSha256Result=true
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
elif command -v sha256sum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c >/dev/null 2>&1; then
wrapperSha256Result=true
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $wrapperSha256Result = false ]; then
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$JAVA_HOME" ] \
&& JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
[ -n "$CLASSPATH" ] \
&& CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
[ -n "$MAVEN_PROJECTBASEDIR" ] \
&& MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
export MAVEN_CMD_LINE_ARGS
# Find the actual extracted directory name (handles snapshots where filename != directory name)
actualDistributionDir=""
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
# First try the expected directory name (for regular distributions)
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
actualDistributionDir="$distributionUrlNameMain"
fi
fi
# shellcheck disable=SC2086 # safe args
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
# If not found, search for any directory with the Maven executable (for snapshots)
if [ -z "$actualDistributionDir" ]; then
# enable globbing to iterate over items
set +f
for dir in "$TMP_DOWNLOAD_DIR"/*; do
if [ -d "$dir" ]; then
if [ -f "$dir/bin/$MVN_CMD" ]; then
actualDistributionDir="$(basename "$dir")"
break
fi
fi
done
set -f
fi
if [ -z "$actualDistributionDir" ]; then
verbose "Contents of $TMP_DOWNLOAD_DIR:"
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
die "Could not find Maven distribution directory in extracted archive"
fi
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
clean || :
exec_maven "$@"

323
mvnw.cmd vendored
View File

@@ -1,3 +1,4 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@@ -18,189 +19,171 @@
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.3.2
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM Apache Maven Wrapper startup batch script, version 3.3.3
@REM
@REM Optional ENV vars
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo. >&2
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo. >&2
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo. >&2
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo. >&2
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %WRAPPER_URL%
)
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
SET WRAPPER_SHA_256_SUM=""
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
)
IF NOT %WRAPPER_SHA_256_SUM%=="" (
powershell -Command "&{"^
"Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash;"^
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
" Write-Error 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
" Write-Error 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
" Write-Error 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
" exit 1;"^
"}"^
"}"
if ERRORLEVEL 1 goto error
)
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
$MAVEN_M2_PATH = "$HOME/.m2"
if ($env:MAVEN_USER_HOME) {
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
}
:error
set ERROR_CODE=1
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
}
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
$MAVEN_WRAPPER_DISTS = $null
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
} else {
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
}
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
cmd /C exit /B %ERROR_CODE%
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
# Find the actual extracted directory name (handles snapshots where filename != directory name)
$actualDistributionDir = ""
# First try the expected directory name (for regular distributions)
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
$actualDistributionDir = $distributionUrlNameMain
}
# If not found, search for any directory with the Maven executable (for snapshots)
if (!$actualDistributionDir) {
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
if (Test-Path -Path $testPath -PathType Leaf) {
$actualDistributionDir = $_.Name
}
}
}
if (!$actualDistributionDir) {
Write-Error "Could not find Maven distribution directory in extracted archive"
}
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

48
pom.xml
View File

@@ -1,10 +1,9 @@
<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">
<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>de.stklcode.jvault</groupId>
<artifactId>jvault-connector</artifactId>
<version>1.5.0</version>
<version>2.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
@@ -33,7 +32,7 @@
<connection>scm:git:git://github.com/stklcode/jvaultconnector.git</connection>
<developerConnection>scm:git:git@github.com:stklcode/jvaultconnector.git</developerConnection>
<url>https://github.com/stklcode/jvaultconnector</url>
<tag>v1.5.0</tag>
<tag>HEAD</tag>
</scm>
<issueManagement>
@@ -43,32 +42,31 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputTimestamp>2025-04-13T09:25:23Z</project.build.outputTimestamp>
<argLine></argLine>
<argLine />
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.3</version>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.18.3</version>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.12.1</version>
<version>5.13.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.17.0</version>
<version>5.19.0</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -80,19 +78,19 @@
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock</artifactId>
<version>3.12.1</version>
<version>3.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.19.0</version>
<version>2.20.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>3.19.3</version>
<version>3.19.4</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -117,7 +115,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -131,7 +129,8 @@
<configuration>
<argLine>
@{argLine}
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.test=com.fasterxml.jackson.databind
--add-opens
de.stklcode.jvault.connector/de.stklcode.jvault.connector.test=com.fasterxml.jackson.databind
</argLine>
</configuration>
</plugin>
@@ -163,13 +162,6 @@
<argLine>
@{argLine}
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector=ALL-UNNAMED
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.exception=ALL-UNNAMED
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.model=ALL-UNNAMED
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.model.response=ALL-UNNAMED
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.model.response.embedded=ALL-UNNAMED
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.test=com.fasterxml.jackson.databind
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.test=com.fasterxml.jackson.datatype.jsr310
</argLine>
</configuration>
</plugin>
@@ -186,7 +178,7 @@
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>5.1.0.4751</version>
<version> 5.2.0.4988</version>
</plugin>
</plugins>
</pluginManagement>
@@ -195,7 +187,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
<version>3.6.1</version>
<executions>
<execution>
<id>enforce-versions</id>
@@ -252,7 +244,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.2</version>
<version>3.11.3</version>
<configuration>
<source>11</source>
</configuration>
@@ -299,7 +291,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.7</version>
<version>3.2.8</version>
<executions>
<execution>
<id>sign-artifacts</id>
@@ -370,7 +362,7 @@
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>12.1.1</version>
<version>12.1.3</version>
<configuration>
<nvdApiKey>${env.NVD_API_KEY}</nvdApiKey>
<nvdDatafeedUrl>${env.NVD_DATAFEED_URL}</nvdDatafeedUrl>
@@ -394,7 +386,7 @@
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.7.0</version>
<version>0.8.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>

View File

@@ -0,0 +1,217 @@
/*
* Copyright 2016-2025 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.model.AppRole;
import de.stklcode.jvault.connector.model.AppRoleSecret;
import de.stklcode.jvault.connector.model.Token;
import de.stklcode.jvault.connector.model.TokenRole;
import de.stklcode.jvault.connector.model.response.*;
import java.util.ArrayList;
import java.util.List;
/**
* AppRole client interface.
* Provides methods to interact with Vault's AppRole API.
*
* @since 2.0.0 extracted from {@link VaultConnector}
*/
public interface AppRoleClient {
/**
* Register a new AppRole role from given metamodel.
*
* @param role The role
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
boolean create(final AppRole role) throws VaultConnectorException;
/**
* Register new AppRole role with default policy.
*
* @param roleName The role name
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default boolean create(final String roleName) throws VaultConnectorException {
return create(roleName, new ArrayList<>());
}
/**
* Register new AppRole role with policies.
*
* @param roleName The role name
* @param policies The policies to associate with
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default boolean create(final String roleName, final List<String> policies) throws VaultConnectorException {
return create(roleName, policies, null);
}
/**
* Register new AppRole role with default policy and custom ID.
*
* @param roleName The role name
* @param roleID A custom role ID
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default boolean create(final String roleName, final String roleID) throws VaultConnectorException {
return create(roleName, new ArrayList<>(), roleID);
}
/**
* Register new AppRole role with policies and custom ID.
*
* @param roleName The role name
* @param policies The policies to associate with
* @param roleID A custom role ID
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default boolean create(final String roleName, final List<String> policies, final String roleID)
throws VaultConnectorException {
return create(AppRole.builder(roleName).withTokenPolicies(policies).withId(roleID).build());
}
/**
* Delete AppRole role from Vault.
*
* @param roleName The role name
* @return {@code true} on success
* @throws VaultConnectorException on error
*/
boolean delete(final String roleName) throws VaultConnectorException;
/**
* Lookup an AppRole role.
*
* @param roleName The role name
* @return Result of the lookup
* @throws VaultConnectorException on error
* @since 0.4.0
*/
AppRoleResponse lookup(final String roleName) throws VaultConnectorException;
/**
* Retrieve ID for an AppRole role.
*
* @param roleName The role name
* @return The role ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
String getRoleID(final String roleName) throws VaultConnectorException;
/**
* Set custom ID for an AppRole role.
*
* @param roleName The role name
* @param roleID The role ID
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
boolean setRoleID(final String roleName, final String roleID) throws VaultConnectorException;
/**
* Register new random generated AppRole secret.
*
* @param roleName The role name
* @return The secret ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default AppRoleSecretResponse createSecret(final String roleName) throws VaultConnectorException {
return createSecret(roleName, new AppRoleSecret());
}
/**
* Register new AppRole secret with custom ID.
*
* @param roleName The role name
* @param secretID A custom secret ID
* @return The secret ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default AppRoleSecretResponse createSecret(final String roleName, final String secretID)
throws VaultConnectorException {
return createSecret(roleName, new AppRoleSecret(secretID));
}
/**
* Register new AppRole secret with custom ID.
*
* @param roleName The role name
* @param secret The secret meta object
* @return The secret ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
AppRoleSecretResponse createSecret(final String roleName, final AppRoleSecret secret)
throws VaultConnectorException;
/**
* Lookup an AppRole secret.
*
* @param roleName The role name
* @param secretID The secret ID
* @return Result of the lookup
* @throws VaultConnectorException on error
* @since 0.4.0
*/
AppRoleSecretResponse lookupSecret(final String roleName, final String secretID)
throws VaultConnectorException;
/**
* Destroy an AppRole secret.
*
* @param roleName The role name
* @param secretID The secret meta object
* @return The secret ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
boolean destroySecret(final String roleName, final String secretID) throws VaultConnectorException;
/**
* List existing (accessible) AppRole roles.
*
* @return List of roles
* @throws VaultConnectorException on error
*/
List<String> listRoles() throws VaultConnectorException;
/**
* List existing (accessible) secret IDs for AppRole role.
*
* @param roleName The role name
* @return List of roles
* @throws VaultConnectorException on error
*/
List<String> listSecrets(final String roleName) throws VaultConnectorException;
}

View File

@@ -0,0 +1,200 @@
/*
* Copyright 2016-2025 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.model.response.MetadataResponse;
import de.stklcode.jvault.connector.model.response.SecretResponse;
import de.stklcode.jvault.connector.model.response.SecretVersionResponse;
import java.util.Map;
/**
* KV v2 client interface.
* Provides methods to interact with Vault's KV v2 API.
*
* @since 2.0.0 extracted from {@link VaultConnector}
*/
public interface KV2Client {
/**
* Retrieve the latest secret data for specific version from Vault.
* <br>
* Path {@code <mount>/data/<key>} is read here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @return Secret response
* @throws VaultConnectorException on error
* @since 0.8
*/
default SecretResponse readData(final String mount, final String key) throws VaultConnectorException {
return readVersion(mount, key, null);
}
/**
* Write secret to Vault.
* <br>
* Path {@code <mount>/data/<key>} is written here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @param data Secret content. Value must be be JSON serializable.
* @return Metadata for the created/updated secret.
* @throws VaultConnectorException on error
* @since 0.8
*/
default SecretVersionResponse writeData(final String mount,
final String key,
final Map<String, Object> data) throws VaultConnectorException {
return writeData(mount, key, data, null);
}
/**
* Write secret to Vault.
* <br>
* Path {@code <mount>/data/<key>} is written here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @param data Secret content. Value must be be JSON serializable.
* @param cas Use Check-And-Set operation, i.e. only allow writing if current version matches this value.
* @return Metadata for the created/updated secret.
* @throws VaultConnectorException on error
* @since 0.8
*/
SecretVersionResponse writeData(final String mount,
final String key,
final Map<String, Object> data,
final Integer cas) throws VaultConnectorException;
/**
* Retrieve secret data from Vault.
* <br>
* Path {@code <mount>/data/<key>} is read here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @param version Version to read. If {@code null} or zero, the latest version will be returned.
* @return Secret response.
* @throws VaultConnectorException on error
* @since 0.8
*/
SecretResponse readVersion(final String mount, final String key, final Integer version)
throws VaultConnectorException;
/**
* Retrieve secret metadata from Vault.
* <br>
* Path {@code <mount>/metadata/<key>} is read here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @return Metadata response
* @throws VaultConnectorException on error
* @since 0.8
*/
MetadataResponse readMetadata(final String mount, final String key) throws VaultConnectorException;
/**
* Update secret metadata.
* <br>
* Path {@code <mount>/metadata/<key>} is written here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @param maxVersions Maximum number of versions (fallback to backend default if {@code null})
* @param casRequired Specify if Check-And-Set is required for this secret.
* @throws VaultConnectorException on error
* @since 0.8
*/
void updateMetadata(final String mount,
final String key,
final Integer maxVersions,
final boolean casRequired) throws VaultConnectorException;
/**
* Delete latest version of a secret from Vault.
* <br>
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @throws VaultConnectorException on error
* @since 0.8
*/
void deleteLatestVersion(final String mount, final String key) throws VaultConnectorException;
/**
* Delete latest version of a secret from Vault.
* <br>
* Prefix {@code secret/} is automatically added to path.
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @throws VaultConnectorException on error
* @since 0.8
*/
void deleteAllVersions(final String mount, final String key) throws VaultConnectorException;
/**
* Delete secret versions from Vault.
* <br>
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @param versions Versions of the secret to delete.
* @throws VaultConnectorException on error
* @since 0.8
*/
void deleteVersions(final String mount, final String key, final int... versions)
throws VaultConnectorException;
/**
* Undelete (restore) secret versions from Vault.
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @param versions Versions of the secret to undelete.
* @throws VaultConnectorException on error
* @since 0.8
*/
void undeleteVersions(final String mount, final String key, final int... versions)
throws VaultConnectorException;
/**
* Destroy secret versions from Vault.
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @param versions Versions of the secret to destroy.
* @throws VaultConnectorException on error
* @since 0.8
*/
void destroyVersions(final String mount, final String key, final int... versions)
throws VaultConnectorException;
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2016-2025 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.model.AuthBackend;
import de.stklcode.jvault.connector.model.Token;
import de.stklcode.jvault.connector.model.TokenRole;
import de.stklcode.jvault.connector.model.response.*;
import java.util.List;
/**
* Sys client interface.
* Provides methods to interact with Vault's system API.
*
* @since 2.0.0 extracted from {@link VaultConnector}
*/
public interface SysClient {
/**
* Retrieve status of vault seal.
*
* @return Seal status
* @throws VaultConnectorException on error
*/
SealResponse sealStatus() throws VaultConnectorException;
/**
* Seal vault.
*
* @throws VaultConnectorException on error
*/
void seal() throws VaultConnectorException;
/**
* Unseal vault.
*
* @param key A single master share key
* @param reset Discard previously provided keys (optional)
* @return Response with seal status
* @throws VaultConnectorException on error
*/
SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException;
/**
* Unseal vault.
*
* @param key A single master share key
* @return Response with seal status
* @throws VaultConnectorException on error
*/
default SealResponse unseal(final String key) throws VaultConnectorException {
return unseal(key, null);
}
/**
* Query server health information.
*
* @return Health information.
* @throws VaultConnectorException on error
* @since 0.7.0
*/
HealthResponse getHealth() throws VaultConnectorException;
/**
* Get all available authentication backends.
*
* @return List of backends
* @throws VaultConnectorException on error
*/
List<AuthBackend> getAuthBackends() throws VaultConnectorException;
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2016-2025 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.model.Token;
import de.stklcode.jvault.connector.model.TokenRole;
import de.stklcode.jvault.connector.model.response.AuthResponse;
import de.stklcode.jvault.connector.model.response.TokenResponse;
import de.stklcode.jvault.connector.model.response.TokenRoleResponse;
import java.util.List;
/**
* Token client interface.
* Provides methods to interact with Vault's token API.
*
* @since 2.0.0 extracted from {@link VaultConnector}
*/
public interface TokenClient {
/**
* Create a new token.
*
* @param token the token
* @return the result response
* @throws VaultConnectorException on error
*/
AuthResponse create(final Token token) throws VaultConnectorException;
/**
* Create a new token.
*
* @param token the token
* @param orphan create orphan token
* @return the result response
* @throws VaultConnectorException on error
*/
AuthResponse create(final Token token, boolean orphan) throws VaultConnectorException;
/**
* Create a new token for specific role.
*
* @param token the token
* @param role the role name
* @return the result response
* @throws VaultConnectorException on error
*/
AuthResponse create(final Token token, final String role) throws VaultConnectorException;
/**
* Lookup token information.
*
* @param token the token
* @return the result response
* @throws VaultConnectorException on error
*/
TokenResponse lookup(final String token) throws VaultConnectorException;
/**
* Create a new or update an existing token role.
*
* @param role the role entity (name must be set)
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.9
*/
default boolean createOrUpdateRole(final TokenRole role) throws VaultConnectorException {
return createOrUpdateRole(role.getName(), role);
}
/**
* Create a new or update an existing token role.
*
* @param name the role name (overrides name possibly set in role entity)
* @param role the role entity
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.9
*/
boolean createOrUpdateRole(final String name, final TokenRole role) throws VaultConnectorException;
/**
* Lookup token information.
*
* @param name the role name
* @return the result response
* @throws VaultConnectorException on error
* @since 0.9
*/
TokenRoleResponse readRole(final String name) throws VaultConnectorException;
/**
* List available token roles from Vault.
*
* @return List of token roles
* @throws VaultConnectorException on error
* @since 0.9
*/
List<String> listRoles() throws VaultConnectorException;
/**
* Delete a token role.
*
* @param name the role name to delete
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.9
*/
boolean deleteRole(final String name) throws VaultConnectorException;
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright 2016-2025 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.model.response.TransitResponse;
import java.util.Base64;
/**
* Transit client interface.
* Provides methods to interact with Vault's transit API.
*
* @since 2.0.0 extracted from {@link VaultConnector}
*/
public interface TransitClient {
/**
* Encrypt plaintext via transit engine from Vault.
*
* @param keyName Transit key name
* @param plaintext Text to encrypt (Base64 encoded)
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
TransitResponse encrypt(final String keyName, final String plaintext) throws VaultConnectorException;
/**
* Encrypt plaintext via transit engine from Vault.
*
* @param keyName Transit key name
* @param plaintext Binary data to encrypt
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
default TransitResponse encrypt(final String keyName, final byte[] plaintext)
throws VaultConnectorException {
return encrypt(keyName, Base64.getEncoder().encodeToString(plaintext));
}
/**
* Decrypt ciphertext via transit engine from Vault.
*
* @param keyName Transit key name
* @param ciphertext Text to decrypt
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
TransitResponse decrypt(final String keyName, final String ciphertext) throws VaultConnectorException;
/**
* Hash data in hex format via transit engine from Vault.
*
* @param algorithm Specifies the hash algorithm to use
* @param input Data to hash
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
default TransitResponse hash(final String algorithm, final String input) throws VaultConnectorException {
return hash(algorithm, input, "hex");
}
/**
* Hash data via transit engine from Vault.
*
* @param algorithm Specifies the hash algorithm to use
* @param input Data to hash (Base64 encoded)
* @param format Specifies the output encoding (hex/base64)
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
TransitResponse hash(final String algorithm, final String input, final String format)
throws VaultConnectorException;
/**
* Hash data via transit engine from Vault.
*
* @param algorithm Specifies the hash algorithm to use
* @param input Data to hash
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
default TransitResponse hash(final String algorithm, final byte[] input, final String format)
throws VaultConnectorException {
return hash(algorithm, Base64.getEncoder().encodeToString(input), format);
}
}

View File

@@ -37,59 +37,6 @@ public interface VaultConnector extends AutoCloseable, Serializable {
*/
void resetAuth();
/**
* Retrieve status of vault seal.
*
* @return Seal status
* @throws VaultConnectorException on error
*/
SealResponse sealStatus() throws VaultConnectorException;
/**
* Seal vault.
*
* @throws VaultConnectorException on error
*/
void seal() throws VaultConnectorException;
/**
* Unseal vault.
*
* @param key A single master share key
* @param reset Discard previously provided keys (optional)
* @return Response with seal status
* @throws VaultConnectorException on error
*/
SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException;
/**
* Unseal vault.
*
* @param key A single master share key
* @return Response with seal status
* @throws VaultConnectorException on error
*/
default SealResponse unseal(final String key) throws VaultConnectorException {
return unseal(key, null);
}
/**
* Query server health information.
*
* @return Health information.
* @throws VaultConnectorException on error
* @since 0.7.0
*/
HealthResponse getHealth() throws VaultConnectorException;
/**
* Get all available authentication backends.
*
* @return List of backends
* @throws VaultConnectorException on error
*/
List<AuthBackend> getAuthBackends() throws VaultConnectorException;
/**
* Authorize to Vault using token.
*
@@ -132,187 +79,6 @@ public interface VaultConnector extends AutoCloseable, Serializable {
*/
AuthResponse authAppRole(final String roleID, final String secretID) throws VaultConnectorException;
/**
* Register a new AppRole role from given metamodel.
*
* @param role The role
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
boolean createAppRole(final AppRole role) throws VaultConnectorException;
/**
* Register new AppRole role with default policy.
*
* @param roleName The role name
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default boolean createAppRole(final String roleName) throws VaultConnectorException {
return createAppRole(roleName, new ArrayList<>());
}
/**
* Register new AppRole role with policies.
*
* @param roleName The role name
* @param policies The policies to associate with
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default boolean createAppRole(final String roleName, final List<String> policies) throws VaultConnectorException {
return createAppRole(roleName, policies, null);
}
/**
* Register new AppRole role with default policy and custom ID.
*
* @param roleName The role name
* @param roleID A custom role ID
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default boolean createAppRole(final String roleName, final String roleID) throws VaultConnectorException {
return createAppRole(roleName, new ArrayList<>(), roleID);
}
/**
* Register new AppRole role with policies and custom ID.
*
* @param roleName The role name
* @param policies The policies to associate with
* @param roleID A custom role ID
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default boolean createAppRole(final String roleName, final List<String> policies, final String roleID)
throws VaultConnectorException {
return createAppRole(AppRole.builder(roleName).withTokenPolicies(policies).withId(roleID).build());
}
/**
* Delete AppRole role from Vault.
*
* @param roleName The role name
* @return {@code true} on success
* @throws VaultConnectorException on error
*/
boolean deleteAppRole(final String roleName) throws VaultConnectorException;
/**
* Lookup an AppRole role.
*
* @param roleName The role name
* @return Result of the lookup
* @throws VaultConnectorException on error
* @since 0.4.0
*/
AppRoleResponse lookupAppRole(final String roleName) throws VaultConnectorException;
/**
* Retrieve ID for an AppRole role.
*
* @param roleName The role name
* @return The role ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
String getAppRoleID(final String roleName) throws VaultConnectorException;
/**
* Set custom ID for an AppRole role.
*
* @param roleName The role name
* @param roleID The role ID
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.4.0
*/
boolean setAppRoleID(final String roleName, final String roleID) throws VaultConnectorException;
/**
* Register new random generated AppRole secret.
*
* @param roleName The role name
* @return The secret ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default AppRoleSecretResponse createAppRoleSecret(final String roleName) throws VaultConnectorException {
return createAppRoleSecret(roleName, new AppRoleSecret());
}
/**
* Register new AppRole secret with custom ID.
*
* @param roleName The role name
* @param secretID A custom secret ID
* @return The secret ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
default AppRoleSecretResponse createAppRoleSecret(final String roleName, final String secretID)
throws VaultConnectorException {
return createAppRoleSecret(roleName, new AppRoleSecret(secretID));
}
/**
* Register new AppRole secret with custom ID.
*
* @param roleName The role name
* @param secret The secret meta object
* @return The secret ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
AppRoleSecretResponse createAppRoleSecret(final String roleName, final AppRoleSecret secret)
throws VaultConnectorException;
/**
* Lookup an AppRole secret.
*
* @param roleName The role name
* @param secretID The secret ID
* @return Result of the lookup
* @throws VaultConnectorException on error
* @since 0.4.0
*/
AppRoleSecretResponse lookupAppRoleSecret(final String roleName, final String secretID)
throws VaultConnectorException;
/**
* Destroy an AppRole secret.
*
* @param roleName The role name
* @param secretID The secret meta object
* @return The secret ID
* @throws VaultConnectorException on error
* @since 0.4.0
*/
boolean destroyAppRoleSecret(final String roleName, final String secretID) throws VaultConnectorException;
/**
* List existing (accessible) AppRole roles.
*
* @return List of roles
* @throws VaultConnectorException on error
*/
List<String> listAppRoles() throws VaultConnectorException;
/**
* List existing (accessible) secret IDs for AppRole role.
*
* @param roleName The role name
* @return List of roles
* @throws VaultConnectorException on error
*/
List<String> listAppRoleSecrets(final String roleName) throws VaultConnectorException;
/**
* Get authorization status.
*
@@ -330,108 +96,6 @@ public interface VaultConnector extends AutoCloseable, Serializable {
*/
SecretResponse read(final String key) throws VaultConnectorException;
/**
* Retrieve the latest secret data for specific version from Vault.
* <br>
* Path {@code <mount>/data/<key>} is read here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @return Secret response
* @throws VaultConnectorException on error
* @since 0.8
*/
default SecretResponse readSecretData(final String mount, final String key) throws VaultConnectorException {
return readSecretVersion(mount, key, null);
}
/**
* Write secret to Vault.
* <br>
* Path {@code <mount>/data/<key>} is written here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @param data Secret content. Value must be be JSON serializable.
* @return Metadata for the created/updated secret.
* @throws VaultConnectorException on error
* @since 0.8
*/
default SecretVersionResponse writeSecretData(final String mount,
final String key,
final Map<String, Object> data) throws VaultConnectorException {
return writeSecretData(mount, key, data, null);
}
/**
* Write secret to Vault.
* <br>
* Path {@code <mount>/data/<key>} is written here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @param data Secret content. Value must be be JSON serializable.
* @param cas Use Check-And-Set operation, i.e. only allow writing if current version matches this value.
* @return Metadata for the created/updated secret.
* @throws VaultConnectorException on error
* @since 0.8
*/
SecretVersionResponse writeSecretData(final String mount,
final String key,
final Map<String, Object> data,
final Integer cas) throws VaultConnectorException;
/**
* Retrieve secret data from Vault.
* <br>
* Path {@code <mount>/data/<key>} is read here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @param version Version to read. If {@code null} or zero, the latest version will be returned.
* @return Secret response.
* @throws VaultConnectorException on error
* @since 0.8
*/
SecretResponse readSecretVersion(final String mount, final String key, final Integer version)
throws VaultConnectorException;
/**
* Retrieve secret metadata from Vault.
* <br>
* Path {@code <mount>/metadata/<key>} is read here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @return Metadata response
* @throws VaultConnectorException on error
* @since 0.8
*/
MetadataResponse readSecretMetadata(final String mount, final String key) throws VaultConnectorException;
/**
* Update secret metadata.
* <br>
* Path {@code <mount>/metadata/<key>} is written here.
* Only available for KV v2 secrets.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret identifier
* @param maxVersions Maximum number of versions (fallback to backend default if {@code null})
* @param casRequired Specify if Check-And-Set is required for this secret.
* @throws VaultConnectorException on error
* @since 0.8
*/
void updateSecretMetadata(final String mount,
final String key,
final Integer maxVersions,
final boolean casRequired) throws VaultConnectorException;
/**
* List available nodes from Vault.
*
@@ -487,71 +151,6 @@ public interface VaultConnector extends AutoCloseable, Serializable {
*/
void delete(final String key) throws VaultConnectorException;
/**
* Delete latest version of a secret from Vault.
* <br>
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @throws VaultConnectorException on error
* @since 0.8
*/
void deleteLatestSecretVersion(final String mount, final String key) throws VaultConnectorException;
/**
* Delete latest version of a secret from Vault.
* <br>
* Prefix {@code secret/} is automatically added to path.
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @throws VaultConnectorException on error
* @since 0.8
*/
void deleteAllSecretVersions(final String mount, final String key) throws VaultConnectorException;
/**
* Delete secret versions from Vault.
* <br>
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @param versions Versions of the secret to delete.
* @throws VaultConnectorException on error
* @since 0.8
*/
void deleteSecretVersions(final String mount, final String key, final int... versions)
throws VaultConnectorException;
/**
* Undelete (restore) secret versions from Vault.
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @param versions Versions of the secret to undelete.
* @throws VaultConnectorException on error
* @since 0.8
*/
void undeleteSecretVersions(final String mount, final String key, final int... versions)
throws VaultConnectorException;
/**
* Destroy secret versions from Vault.
* Only available for KV v2 stores.
*
* @param mount Secret store mount point (without leading or trailing slash).
* @param key Secret path.
* @param versions Versions of the secret to destroy.
* @throws VaultConnectorException on error
* @since 0.8
*/
void destroySecretVersions(final String mount, final String key, final int... versions)
throws VaultConnectorException;
/**
* Revoke given lease immediately.
*
@@ -582,170 +181,44 @@ public interface VaultConnector extends AutoCloseable, Serializable {
SecretResponse renew(final String leaseID, final Integer increment) throws VaultConnectorException;
/**
* Create a new token.
* Get client for KV v2 API.
*
* @param token the token
* @return the result response
* @throws VaultConnectorException on error
* @return KV v2 client
* @since 2.0.0
*/
AuthResponse createToken(final Token token) throws VaultConnectorException;
KV2Client kv2();
/**
* Create a new token.
* Get client for token API.
*
* @param token the token
* @param orphan create orphan token
* @return the result response
* @throws VaultConnectorException on error
* @return Token client
* @since 2.0.0
*/
AuthResponse createToken(final Token token, boolean orphan) throws VaultConnectorException;
TokenClient token();
/**
* Create a new token for specific role.
* Get client for AppRole API.
*
* @param token the token
* @param role the role name
* @return the result response
* @throws VaultConnectorException on error
* @return AppRole client
* @since 2.0.0
*/
AuthResponse createToken(final Token token, final String role) throws VaultConnectorException;
AppRoleClient appRole();
/**
* Lookup token information.
* Get client for transit API.
*
* @param token the token
* @return the result response
* @throws VaultConnectorException on error
* @return Transit client
* @since 2.0.0
*/
TokenResponse lookupToken(final String token) throws VaultConnectorException;
TransitClient transit();
/**
* Create a new or update an existing token role.
* Get client for system API.
*
* @param role the role entity (name must be set)
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.9
* @return System client
* @since 2.0.0
*/
default boolean createOrUpdateTokenRole(final TokenRole role) throws VaultConnectorException {
return createOrUpdateTokenRole(role.getName(), role);
}
/**
* Create a new or update an existing token role.
*
* @param name the role name (overrides name possibly set in role entity)
* @param role the role entity
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.9
*/
boolean createOrUpdateTokenRole(final String name, final TokenRole role) throws VaultConnectorException;
/**
* Lookup token information.
*
* @param name the role name
* @return the result response
* @throws VaultConnectorException on error
* @since 0.9
*/
TokenRoleResponse readTokenRole(final String name) throws VaultConnectorException;
/**
* List available token roles from Vault.
*
* @return List of token roles
* @throws VaultConnectorException on error
* @since 0.9
*/
List<String> listTokenRoles() throws VaultConnectorException;
/**
* Delete a token role.
*
* @param name the role name to delete
* @return {@code true} on success
* @throws VaultConnectorException on error
* @since 0.9
*/
boolean deleteTokenRole(final String name) throws VaultConnectorException;
/**
* Encrypt plaintext via transit engine from Vault.
*
* @param keyName Transit key name
* @param plaintext Text to encrypt (Base64 encoded)
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
TransitResponse transitEncrypt(final String keyName, final String plaintext) throws VaultConnectorException;
/**
* Encrypt plaintext via transit engine from Vault.
*
* @param keyName Transit key name
* @param plaintext Binary data to encrypt
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
default TransitResponse transitEncrypt(final String keyName, final byte[] plaintext)
throws VaultConnectorException {
return transitEncrypt(keyName, Base64.getEncoder().encodeToString(plaintext));
}
/**
* Decrypt ciphertext via transit engine from Vault.
*
* @param keyName Transit key name
* @param ciphertext Text to decrypt
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
TransitResponse transitDecrypt(final String keyName, final String ciphertext) throws VaultConnectorException;
/**
* Hash data in hex format via transit engine from Vault.
*
* @param algorithm Specifies the hash algorithm to use
* @param input Data to hash
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
default TransitResponse transitHash(final String algorithm, final String input) throws VaultConnectorException {
return transitHash(algorithm, input, "hex");
}
/**
* Hash data via transit engine from Vault.
*
* @param algorithm Specifies the hash algorithm to use
* @param input Data to hash (Base64 encoded)
* @param format Specifies the output encoding (hex/base64)
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
TransitResponse transitHash(final String algorithm, final String input, final String format)
throws VaultConnectorException;
/**
* Hash data via transit engine from Vault.
*
* @param algorithm Specifies the hash algorithm to use
* @param input Data to hash
* @return Transit response
* @throws VaultConnectorException on error
* @since 1.5.0
*/
default TransitResponse transitHash(final String algorithm, final byte[] input, final String format)
throws VaultConnectorException {
return transitHash(algorithm, Base64.getEncoder().encodeToString(input), format);
}
SysClient sys();
/**
* Read credentials for MySQL backend at default mount point.
@@ -816,4 +289,5 @@ public interface VaultConnector extends AutoCloseable, Serializable {
throws VaultConnectorException {
return (CredentialsResponse) read(mount + "/creds/" + role);
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2016-2025 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector.internal;
/**
* Vault API path constants.
*
* @author Stefan Kalscheuer
* @since 1.5.3
*/
public final class VaultApiPath {
// Base paths
private static final String SYS = "sys";
private static final String AUTH = "auth";
private static final String TRANSIT = "transit";
// System paths
public static final String SYS_AUTH = SYS + "/auth";
public static final String SYS_LEASES_RENEW = SYS + "/leases/renew";
public static final String SYS_LEASES_REVOKE = SYS + "/leases/revoke/";
public static final String SYS_HEALTH = SYS + "/health";
public static final String SYS_SEAL = SYS + "/seal";
public static final String SYS_SEAL_STATUS = SYS + "/seal-status";
public static final String SYS_UNSEAL = SYS + "/unseal";
// Auth paths
public static final String AUTH_TOKEN = AUTH + "/token";
public static final String AUTH_USERPASS_LOGIN = AUTH + "/userpass/login/";
public static final String AUTH_APPROLE = AUTH + "/approle";
public static final String AUTH_APPROLE_ROLE = AUTH_APPROLE + "/role/%s%s";
// Token operations
public static final String TOKEN_LOOKUP = "/lookup";
public static final String TOKEN_LOOKUP_SELF = "/lookup-self";
public static final String TOKEN_CREATE = "/create";
public static final String TOKEN_CREATE_ORPHAN = "/create-orphan";
public static final String TOKEN_ROLES = "/roles";
// Secret engine paths
public static final String SECRET_DATA = "/data/";
public static final String SECRET_METADATA = "/metadata/";
public static final String SECRET_DELETE = "/delete/";
public static final String SECRET_UNDELETE = "/undelete/";
public static final String SECRET_DESTROY = "/destroy/";
// Generic paths
public static final String LOGIN = "/login";
// Transit engine paths
public static final String TRANSIT_ENCRYPT = TRANSIT + "/encrypt/";
public static final String TRANSIT_DECRYPT = TRANSIT + "/decrypt/";
public static final String TRANSIT_HASH = TRANSIT + "/hash/";
/**
* Private constructor to prevent instantiation.
*/
private VaultApiPath() {
// Utility class
}
}

View File

@@ -32,7 +32,7 @@ import java.util.Objects;
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public final class AppRole implements Serializable {
private static final long serialVersionUID = 693228837510483448L;
private static final long serialVersionUID = 1546673231280751679L;
@JsonProperty("role_name")
private String name;
@@ -53,7 +53,7 @@ public final class AppRole implements Serializable {
@JsonProperty("secret_id_ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer secretIdTtl;
private Long secretIdTtl;
@JsonProperty("local_secret_ids")
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -61,11 +61,11 @@ public final class AppRole implements Serializable {
@JsonProperty("token_ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer tokenTtl;
private Long tokenTtl;
@JsonProperty("token_max_ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer tokenMaxTtl;
private Long tokenMaxTtl;
private List<String> tokenPolicies;
@@ -75,7 +75,7 @@ public final class AppRole implements Serializable {
@JsonProperty("token_explicit_max_ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer tokenExplicitMaxTtl;
private Long tokenExplicitMaxTtl;
@JsonProperty("token_no_default_policy")
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -255,7 +255,7 @@ public final class AppRole implements Serializable {
/**
* @return maximum TTL in seconds for secrets
*/
public Integer getSecretIdTtl() {
public Long getSecretIdTtl() {
return secretIdTtl;
}
@@ -271,14 +271,14 @@ public final class AppRole implements Serializable {
/**
* @return token TTL in seconds
*/
public Integer getTokenTtl() {
public Long getTokenTtl() {
return tokenTtl;
}
/**
* @return maximum token TTL in seconds, including renewals
*/
public Integer getTokenMaxTtl() {
public Long getTokenMaxTtl() {
return tokenMaxTtl;
}
@@ -286,7 +286,7 @@ public final class AppRole implements Serializable {
* @return explicit maximum token TTL in seconds, including renewals
* @since 0.9
*/
public Integer getTokenExplicitMaxTtl() {
public Long getTokenExplicitMaxTtl() {
return tokenExplicitMaxTtl;
}
@@ -370,12 +370,12 @@ public final class AppRole implements Serializable {
private List<String> secretIdBoundCidrs;
private List<String> tokenPolicies;
private Integer secretIdNumUses;
private Integer secretIdTtl;
private Long secretIdTtl;
private Boolean localSecretIds;
private Integer tokenTtl;
private Integer tokenMaxTtl;
private Long tokenTtl;
private Long tokenMaxTtl;
private List<String> tokenBoundCidrs;
private Integer tokenExplicitMaxTtl;
private Long tokenExplicitMaxTtl;
private Boolean tokenNoDefaultPolicy;
private Integer tokenNumUses;
private Integer tokenPeriod;
@@ -520,7 +520,7 @@ public final class AppRole implements Serializable {
* @param secretIdTtl the TTL
* @return self
*/
public Builder withSecretIdTtl(final Integer secretIdTtl) {
public Builder withSecretIdTtl(final Long secretIdTtl) {
this.secretIdTtl = secretIdTtl;
return this;
}
@@ -544,7 +544,7 @@ public final class AppRole implements Serializable {
* @param tokenTtl the TTL
* @return self
*/
public Builder withTokenTtl(final Integer tokenTtl) {
public Builder withTokenTtl(final Long tokenTtl) {
this.tokenTtl = tokenTtl;
return this;
}
@@ -555,7 +555,7 @@ public final class AppRole implements Serializable {
* @param tokenMaxTtl the TTL
* @return self
*/
public Builder withTokenMaxTtl(final Integer tokenMaxTtl) {
public Builder withTokenMaxTtl(final Long tokenMaxTtl) {
this.tokenMaxTtl = tokenMaxTtl;
return this;
}
@@ -596,7 +596,7 @@ public final class AppRole implements Serializable {
* @param tokenExplicitMaxTtl the TTL
* @return self
*/
public Builder withTokenExplicitMaxTtl(final Integer tokenExplicitMaxTtl) {
public Builder withTokenExplicitMaxTtl(final Long tokenExplicitMaxTtl) {
this.tokenExplicitMaxTtl = tokenExplicitMaxTtl;
return this;
}

View File

@@ -32,7 +32,7 @@ import java.util.*;
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public final class Token implements Serializable {
private static final long serialVersionUID = 5208508683665365287L;
private static final long serialVersionUID = 7003016071684507115L;
@JsonProperty("id")
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -56,11 +56,11 @@ public final class Token implements Serializable {
@JsonProperty("ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer ttl;
private Long ttl;
@JsonProperty("explicit_max_ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer explicitMaxTtl;
private Long explicitMaxTtl;
@JsonProperty("num_uses")
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -162,7 +162,7 @@ public final class Token implements Serializable {
/**
* @return Time-to-live in seconds
*/
public Integer getTtl() {
public Long getTtl() {
return ttl;
}
@@ -170,7 +170,7 @@ public final class Token implements Serializable {
* @return Explicit maximum time-to-live in seconds
* @since 0.9
*/
public Integer getExplicitMaxTtl() {
public Long getExplicitMaxTtl() {
return explicitMaxTtl;
}
@@ -282,8 +282,8 @@ public final class Token implements Serializable {
private String displayName;
private Boolean noParent;
private Boolean noDefaultPolicy;
private Integer ttl;
private Integer explicitMaxTtl;
private Long ttl;
private Long explicitMaxTtl;
private Integer numUses;
private List<String> policies;
private Map<String, String> meta;
@@ -331,7 +331,7 @@ public final class Token implements Serializable {
* @param ttl the ttl
* @return self
*/
public Builder withTtl(final Integer ttl) {
public Builder withTtl(final Long ttl) {
this.ttl = ttl;
return this;
}
@@ -342,7 +342,7 @@ public final class Token implements Serializable {
* @param explicitMaxTtl the explicit max. TTL
* @return self
*/
public Builder withExplicitMaxTtl(final Integer explicitMaxTtl) {
public Builder withExplicitMaxTtl(final Long explicitMaxTtl) {
this.explicitMaxTtl = explicitMaxTtl;
return this;
}

View File

@@ -34,7 +34,7 @@ import java.util.Objects;
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public final class TokenRole implements Serializable {
private static final long serialVersionUID = -3505215215838576321L;
private static final long serialVersionUID = -4856948364869438439L;
@JsonProperty("name")
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -78,7 +78,7 @@ public final class TokenRole implements Serializable {
@JsonProperty("token_explicit_max_ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer tokenExplicitMaxTtl;
private Long tokenExplicitMaxTtl;
@JsonProperty("token_no_default_policy")
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -204,7 +204,7 @@ public final class TokenRole implements Serializable {
/**
* @return Token explicit maximum TTL
*/
public Integer getTokenExplicitMaxTtl() {
public Long getTokenExplicitMaxTtl() {
return tokenExplicitMaxTtl;
}
@@ -285,7 +285,7 @@ public final class TokenRole implements Serializable {
private String pathSuffix;
private List<String> allowedEntityAliases;
private List<String> tokenBoundCidrs;
private Integer tokenExplicitMaxTtl;
private Long tokenExplicitMaxTtl;
private Boolean tokenNoDefaultPolicy;
private Integer tokenNumUses;
private Integer tokenPeriod;
@@ -537,7 +537,7 @@ public final class TokenRole implements Serializable {
* @param tokenExplicitMaxTtl explicit maximum TTL
* @return self
*/
public Builder withTokenExplicitMaxTtl(final Integer tokenExplicitMaxTtl) {
public Builder withTokenExplicitMaxTtl(final Long tokenExplicitMaxTtl) {
this.tokenExplicitMaxTtl = tokenExplicitMaxTtl;
return this;
}

View File

@@ -15,13 +15,13 @@ import java.util.Objects;
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class MountConfig implements Serializable {
private static final long serialVersionUID = -8653909672663717792L;
private static final long serialVersionUID = 7241631159224756605L;
@JsonProperty("default_lease_ttl")
private Integer defaultLeaseTtl;
private Long defaultLeaseTtl;
@JsonProperty("max_lease_ttl")
private Integer maxLeaseTtl;
private Long maxLeaseTtl;
@JsonProperty("force_no_cache")
private Boolean forceNoCache;
@@ -56,14 +56,14 @@ public class MountConfig implements Serializable {
/**
* @return Default lease TTL
*/
public Integer getDefaultLeaseTtl() {
public Long getDefaultLeaseTtl() {
return defaultLeaseTtl;
}
/**
* @return Maximum lease TTL
*/
public Integer getMaxLeaseTtl() {
public Long getMaxLeaseTtl() {
return maxLeaseTtl;
}

View File

@@ -34,7 +34,7 @@ import java.util.Objects;
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public final class TokenData implements Serializable {
private static final long serialVersionUID = -5749716740973138916L;
private static final long serialVersionUID = -4168046151053509784L;
@JsonProperty("accessor")
private String accessor;
@@ -43,7 +43,7 @@ public final class TokenData implements Serializable {
private Integer creationTime;
@JsonProperty("creation_ttl")
private Integer creationTtl;
private Long creationTtl;
@JsonProperty("display_name")
private String name;
@@ -55,7 +55,7 @@ public final class TokenData implements Serializable {
private ZonedDateTime expireTime;
@JsonProperty("explicit_max_ttl")
private Integer explicitMaxTtl;
private Long explicitMaxTtl;
@JsonProperty("id")
private String id;
@@ -82,7 +82,7 @@ public final class TokenData implements Serializable {
private boolean renewable;
@JsonProperty("ttl")
private Integer ttl;
private Long ttl;
@JsonProperty("type")
private String type;
@@ -104,7 +104,7 @@ public final class TokenData implements Serializable {
/**
* @return Creation TTL (in seconds)
*/
public Integer getCreationTtl() {
public Long getCreationTtl() {
return creationTtl;
}
@@ -135,7 +135,7 @@ public final class TokenData implements Serializable {
* @return Explicit maximum TTL
* @since 0.9
*/
public Integer getExplicitMaxTtl() {
public Long getExplicitMaxTtl() {
return explicitMaxTtl;
}
@@ -202,7 +202,7 @@ public final class TokenData implements Serializable {
/**
* @return Token TTL (in seconds)
*/
public Integer getTtl() {
public Long getTtl() {
return ttl;
}

View File

@@ -63,12 +63,12 @@ class HTTPVaultConnectorBuilderTest {
// Specify all options.
HTTPVaultConnectorBuilder builder = HTTPVaultConnector.builder()
.withHost("vault2.example.com")
.withoutTLS()
.withPort(1234)
.withPrefix("/foo/")
.withTimeout(5678)
.withNumberOfRetries(9);
.withHost("vault2.example.com")
.withoutTLS()
.withPort(1234)
.withPrefix("/foo/")
.withTimeout(5678)
.withNumberOfRetries(9);
connector = builder.build();
assertEquals("http://vault2.example.com:1234/foo/", getRequestHelperPrivate(connector, "baseURL"), "URL not set correctly");
@@ -79,13 +79,13 @@ class HTTPVaultConnectorBuilderTest {
// Initialization from URL.
assertThrows(
URISyntaxException.class,
() -> HTTPVaultConnector.builder().withBaseURL("foo:/\\1nv4l1d_UrL"),
"Initialization from invalid URL should fail"
URISyntaxException.class,
() -> HTTPVaultConnector.builder().withBaseURL("foo:/\\1nv4l1d_UrL"),
"Initialization from invalid URL should fail"
);
connector = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().withBaseURL("https://vault3.example.com:5678/bar/").build(),
"Initialization from valid URL should not fail"
() -> HTTPVaultConnector.builder().withBaseURL("https://vault3.example.com:5678/bar/").build(),
"Initialization from valid URL should not fail"
);
assertEquals("https://vault3.example.com:5678/bar/", getRequestHelperPrivate(connector, "baseURL"), "URL not set correctly");
@@ -106,8 +106,8 @@ class HTTPVaultConnectorBuilderTest {
// Provide address only should be enough.
withVaultEnv(VAULT_ADDR, null, null, null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
);
HTTPVaultConnector connector = builder.build();
@@ -119,16 +119,16 @@ class HTTPVaultConnectorBuilderTest {
});
withVaultEnv(VAULT_ADDR_2, null, null, null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
);
assertEquals(VAULT_ADDR_2 + "/v1/", getRequestHelperPrivate(builder.build(), "baseURL"), "URL without port not set correctly");
return null;
});
withVaultEnv(VAULT_ADDR_3, null, null, null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
);
assertEquals(VAULT_ADDR_3, getRequestHelperPrivate(builder.build(), "baseURL"), "URL with custom path not set correctly");
return null;
@@ -137,8 +137,8 @@ class HTTPVaultConnectorBuilderTest {
// Provide address and number of retries.
withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from environment failed"
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from environment failed"
);
HTTPVaultConnector connector = builder.build();
@@ -152,8 +152,8 @@ class HTTPVaultConnectorBuilderTest {
// Automatic authentication.
withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
);
assertEquals(VAULT_TOKEN, getPrivate(builder, "token"), "Token not set correctly");
@@ -163,9 +163,9 @@ class HTTPVaultConnectorBuilderTest {
// Invalid URL.
withVaultEnv("This is not a valid URL!", null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN).execute(() -> {
assertThrows(
ConnectionException.class,
() -> HTTPVaultConnector.builder().fromEnv(),
"Invalid URL from environment should raise an exception"
ConnectionException.class,
() -> HTTPVaultConnector.builder().fromEnv(),
"Invalid URL from environment should raise an exception"
);
return null;
@@ -182,8 +182,8 @@ class HTTPVaultConnectorBuilderTest {
AtomicReference<Object> certFromPem = new AtomicReference<>();
withVaultEnv(VAULT_ADDR, pem, null, null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Builder with PEM certificate from environment failed"
() -> HTTPVaultConnector.builder().fromEnv(),
"Builder with PEM certificate from environment failed"
);
HTTPVaultConnector connector = builder.build();
@@ -198,8 +198,8 @@ class HTTPVaultConnectorBuilderTest {
AtomicReference<Object> certFromFile = new AtomicReference<>();
withVaultEnv(VAULT_ADDR, file, null, null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Builder with certificate path from environment failed"
() -> HTTPVaultConnector.builder().fromEnv(),
"Builder with certificate path from environment failed"
);
HTTPVaultConnector connector = builder.build();
@@ -215,9 +215,9 @@ class HTTPVaultConnectorBuilderTest {
String doesNotExist = tempDir.toString() + "/doesnotexist";
withVaultEnv(VAULT_ADDR, doesNotExist, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
TlsException e = assertThrows(
TlsException.class,
() -> HTTPVaultConnector.builder().fromEnv(),
"Creation with unknown cert path failed"
TlsException.class,
() -> HTTPVaultConnector.builder().fromEnv(),
"Creation with unknown cert path failed"
);
assertEquals(doesNotExist, assertInstanceOf(NoSuchFileException.class, e.getCause()).getFile());
@@ -227,9 +227,9 @@ class HTTPVaultConnectorBuilderTest {
private SystemLambda.WithEnvironmentVariables withVaultEnv(String vaultAddr, String vaultCacert, String vaultMaxRetries, String vaultToken) {
return withEnvironmentVariable("VAULT_ADDR", vaultAddr)
.and("VAULT_CACERT", vaultCacert)
.and("VAULT_MAX_RETRIES", vaultMaxRetries)
.and("VAULT_TOKEN", vaultToken);
.and("VAULT_CACERT", vaultCacert)
.and("VAULT_MAX_RETRIES", vaultMaxRetries)
.and("VAULT_TOKEN", vaultToken);
}
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException {

View File

@@ -17,13 +17,13 @@
package de.stklcode.jvault.connector;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import de.stklcode.jvault.connector.exception.ConnectionException;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.exception.PermissionDeniedException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.api.function.Executable;
import java.io.IOException;
@@ -36,9 +36,7 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collections;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.jupiter.api.Assertions.*;
/**
@@ -48,62 +46,59 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer
* @since 0.7.0
*/
@WireMockTest
class HTTPVaultConnectorTest {
@RegisterExtension
static WireMockExtension wireMock = WireMockExtension.newInstance()
.options(wireMockConfig().dynamicPort())
.build();
/**
* Test exceptions thrown during request.
*/
@Test
void requestExceptionTest() throws IOException, URISyntaxException {
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.url("/")).withTimeout(250).build();
// Test invalid response code.
final int responseCode = 400;
mockHttpResponse(responseCode, "", "application/json");
VaultConnectorException e = assertThrows(
void requestExceptionTest(WireMockRuntimeInfo wireMock) throws IOException, URISyntaxException {
try (var connector = HTTPVaultConnector.builder(wireMock.getHttpBaseUrl()).withTimeout(250).build()) {
// Test invalid response code.
final int responseCode = 400;
mockHttpResponse(responseCode, "", "application/json");
VaultConnectorException e = assertThrows(
InvalidResponseException.class,
connector::getHealth,
() -> connector.sys().getHealth(),
"Querying health status succeeded on invalid instance"
);
assertEquals("Invalid response code", e.getMessage(), "Unexpected exception message");
assertEquals(responseCode, ((InvalidResponseException) e).getStatusCode(), "Unexpected status code in exception");
assertNull(((InvalidResponseException) e).getResponse(), "Response message where none was expected");
);
assertEquals("Invalid response code", e.getMessage(), "Unexpected exception message");
assertEquals(responseCode, ((InvalidResponseException) e).getStatusCode(), "Unexpected status code in exception");
assertNull(((InvalidResponseException) e).getResponse(), "Response message where none was expected");
// Simulate permission denied response.
mockHttpResponse(responseCode, "{\"errors\":[\"permission denied\"]}", "application/json");
assertThrows(
// Simulate permission denied response.
mockHttpResponse(responseCode, "{\"errors\":[\"permission denied\"]}", "application/json");
assertThrows(
PermissionDeniedException.class,
connector::getHealth,
() -> connector.sys().getHealth(),
"Querying health status succeeded on invalid instance"
);
);
}
// Test exception thrown during request.
try (ServerSocket s = new ServerSocket(0)) {
connector = HTTPVaultConnector.builder("http://localst:" + s.getLocalPort() + "/").withTimeout(250).build();
}
e = assertThrows(
try (ServerSocket s = new ServerSocket(0);
var connector = HTTPVaultConnector.builder("http://localst:" + s.getLocalPort() + "/").withTimeout(250).build()) {
var e = assertThrows(
ConnectionException.class,
connector::getHealth,
() -> connector.sys().getHealth(),
"Querying health status succeeded on invalid instance"
);
assertEquals("Unable to connect to Vault server", e.getMessage(), "Unexpected exception message");
assertInstanceOf(IOException.class, e.getCause(), "Unexpected cause");
);
assertEquals("Unable to connect to Vault server", e.getMessage(), "Unexpected exception message");
assertInstanceOf(IOException.class, e.getCause(), "Unexpected cause");
}
// Now simulate a failing request that succeeds on second try.
connector = HTTPVaultConnector.builder(wireMock.url("/")).withNumberOfRetries(1).withTimeout(250).build();
wireMock.stubFor(
try (var connector3 = HTTPVaultConnector.builder(wireMock.getHttpBaseUrl()).withNumberOfRetries(1).withTimeout(250).build()) {
stubFor(
WireMock.any(anyUrl())
.willReturn(aResponse().withStatus(500))
.willReturn(aResponse().withStatus(500))
.willReturn(aResponse().withStatus(500))
.willReturn(aResponse().withStatus(200).withBody("{}").withHeader("Content-Type", "application/json"))
);
assertDoesNotThrow(connector::getHealth, "Request failed unexpectedly");
.willReturn(aResponse().withStatus(500))
.willReturn(aResponse().withStatus(500))
.willReturn(aResponse().withStatus(500))
.willReturn(aResponse().withStatus(200).withBody("{}").withHeader("Content-Type", "application/json"))
);
assertDoesNotThrow(() -> connector3.sys().getHealth(), "Request failed unexpectedly");
}
}
/**
@@ -164,9 +159,9 @@ class HTTPVaultConnectorTest {
connector = HTTPVaultConnector.builder("http://localst:" + s.getLocalPort()).withTimeout(250).build();
}
ConnectionException e = assertThrows(
ConnectionException.class,
connector::sealStatus,
"Querying seal status succeeded on invalid instance"
ConnectionException.class,
() -> connector.sys().sealStatus(),
"Querying seal status succeeded on invalid instance"
);
assertEquals("Unable to connect to Vault server", e.getMessage(), "Unexpected exception message");
}
@@ -182,9 +177,9 @@ class HTTPVaultConnectorTest {
connector = HTTPVaultConnector.builder("http://localhost:" + s.getLocalPort() + "/").withTimeout(250).build();
}
ConnectionException e = assertThrows(
ConnectionException.class,
connector::getHealth,
"Querying health status succeeded on invalid instance"
ConnectionException.class,
() -> connector.sys().getHealth(),
"Querying health status succeeded on invalid instance"
);
assertEquals("Unable to connect to Vault server", e.getMessage(), "Unexpected exception message");
}
@@ -193,29 +188,29 @@ class HTTPVaultConnectorTest {
* Test behavior on unparsable responses.
*/
@Test
void parseExceptionTest() throws URISyntaxException {
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.url("/")).withTimeout(250).build();
void parseExceptionTest(WireMockRuntimeInfo wireMock) throws URISyntaxException {
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.getHttpBaseUrl()).withTimeout(250).build();
// Mock authorization.
setPrivate(connector, "authorized", true);
// Mock response.
mockHttpResponse(200, "invalid", "application/json");
// Now test the methods.
assertParseError(connector::sealStatus, "sealStatus() succeeded on invalid instance");
assertParseError(() -> connector.unseal("key"), "unseal() succeeded on invalid instance");
assertParseError(connector::getHealth, "getHealth() succeeded on invalid instance");
assertParseError(connector::getAuthBackends, "getAuthBackends() succeeded on invalid instance");
assertParseError(() -> connector.sys().sealStatus(), "sys().sealStatus() succeeded on invalid instance");
assertParseError(() -> connector.sys().unseal("key"), "sys().unseal() succeeded on invalid instance");
assertParseError(() -> connector.sys().getHealth(), "sys().getHealth() succeeded on invalid instance");
assertParseError(() -> connector.sys().getAuthBackends(), "sys().getAuthBackends() succeeded on invalid instance");
assertParseError(() -> connector.authToken("token"), "authToken() succeeded on invalid instance");
assertParseError(() -> connector.lookupAppRole("roleName"), "lookupAppRole() succeeded on invalid instance");
assertParseError(() -> connector.getAppRoleID("roleName"), "getAppRoleID() succeeded on invalid instance");
assertParseError(() -> connector.createAppRoleSecret("roleName"), "createAppRoleSecret() succeeded on invalid instance");
assertParseError(() -> connector.lookupAppRoleSecret("roleName", "secretID"), "lookupAppRoleSecret() succeeded on invalid instance");
assertParseError(connector::listAppRoles, "listAppRoles() succeeded on invalid instance");
assertParseError(() -> connector.listAppRoleSecrets("roleName"), "listAppRoleSecrets() succeeded on invalid instance");
assertParseError(() -> connector.appRole().lookup("roleName"), "appRole().lookup() succeeded on invalid instance");
assertParseError(() -> connector.appRole().getRoleID("roleName"), "appRole().getRoleID() succeeded on invalid instance");
assertParseError(() -> connector.appRole().createSecret("roleName"), "appRole().createSecret() succeeded on invalid instance");
assertParseError(() -> connector.appRole().lookupSecret("roleName", "secretID"), "appRole().lookupSecret() succeeded on invalid instance");
assertParseError(() -> connector.appRole().listRoles(), "appRole().listRoles() succeeded on invalid instance");
assertParseError(() -> connector.appRole().listSecrets("roleName"), "appRole().listSecrets() succeeded on invalid instance");
assertParseError(() -> connector.read("key"), "read() succeeded on invalid instance");
assertParseError(() -> connector.list("path"), "list() succeeded on invalid instance");
assertParseError(() -> connector.renew("leaseID"), "renew() succeeded on invalid instance");
assertParseError(() -> connector.lookupToken("token"), "lookupToken() succeeded on invalid instance");
assertParseError(() -> connector.token().lookup("token"), "token().lookup() succeeded on invalid instance");
}
private void assertParseError(Executable executable, String message) {
@@ -227,8 +222,8 @@ class HTTPVaultConnectorTest {
* Test requests that expect an empty response with code 204, but receive a 200 body.
*/
@Test
void nonEmpty204ResponseTest() throws URISyntaxException {
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.url("/")).withTimeout(250).build();
void nonEmpty204ResponseTest(WireMockRuntimeInfo wireMock) throws URISyntaxException {
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.getHttpBaseUrl()).withTimeout(250).build();
// Mock authorization.
setPrivate(connector, "authorized", true);
// Mock response.
@@ -236,45 +231,45 @@ class HTTPVaultConnectorTest {
// Now test the methods expecting a 204.
assertThrows(
InvalidResponseException.class,
() -> connector.createAppRole("appID", Collections.singletonList("policy")),
"createAppRole() with 200 response succeeded"
InvalidResponseException.class,
() -> connector.appRole().create("appID", Collections.singletonList("policy")),
"appRole().create() with 200 response succeeded"
);
assertThrows(
InvalidResponseException.class,
() -> connector.deleteAppRole("roleName"),
"deleteAppRole() with 200 response succeeded"
InvalidResponseException.class,
() -> connector.delete("roleName"),
"appRole().delete() with 200 response succeeded"
);
assertThrows(
InvalidResponseException.class,
() -> connector.setAppRoleID("roleName", "roleID"),
"setAppRoleID() with 200 response succeeded"
InvalidResponseException.class,
() -> connector.appRole().setRoleID("roleName", "roleID"),
"appRole().setRoleID() with 200 response succeeded"
);
assertThrows(
InvalidResponseException.class,
() -> connector.destroyAppRoleSecret("roleName", "secretID"),
"destroyAppRoleSecret() with 200 response succeeded"
InvalidResponseException.class,
() -> connector.appRole().destroySecret("roleName", "secretID"),
"appRole().destroySecret() with 200 response succeeded"
);
assertThrows(
InvalidResponseException.class,
() -> connector.destroyAppRoleSecret("roleName", "secretUD"),
"destroyAppRoleSecret() with 200 response succeeded"
InvalidResponseException.class,
() -> connector.appRole().destroySecret("roleName", "secretUD"),
"appRole().destroySecret() with 200 response succeeded"
);
assertThrows(
InvalidResponseException.class,
() -> connector.delete("key"),
"delete() with 200 response succeeded"
InvalidResponseException.class,
() -> connector.delete("key"),
"delete() with 200 response succeeded"
);
assertThrows(
InvalidResponseException.class,
() -> connector.revoke("leaseID"),
"destroyAppRoleSecret() with 200 response succeeded"
InvalidResponseException.class,
() -> connector.revoke("leaseID"),
"destroyAppRoleSecret() with 200 response succeeded"
);
}
@@ -310,10 +305,10 @@ class HTTPVaultConnectorTest {
}
private void mockHttpResponse(int status, String body, String contentType) {
wireMock.stubFor(
WireMock.any(anyUrl()).willReturn(
aResponse().withStatus(status).withBody(body).withHeader("Content-Type", contentType)
)
stubFor(
WireMock.any(anyUrl()).willReturn(
aResponse().withStatus(status).withBody(body).withHeader("Content-Type", contentType)
)
);
}
}

View File

@@ -35,8 +35,8 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
private static final String TEST_ID = "abc123";
private static final Map<String, Object> TEST_META = Map.of(
"foo", "bar",
"number", 1337
"foo", "bar",
"number", 1337
);
private static final List<String> TEST_CIDR = List.of("203.0.113.0/24", "198.51.100.0/24");
@@ -122,8 +122,8 @@ class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
String secretJson2 = commaSeparatedToList(secretJson);
AppRoleSecret secret2 = assertDoesNotThrow(
() -> objectMapper.readValue(secretJson2, AppRoleSecret.class),
"Deserialization failed"
() -> objectMapper.readValue(secretJson2, AppRoleSecret.class),
"Deserialization failed"
);
assertEquals(secret2.getId(), secret.getId());
assertEquals(secret2.getMetadata(), secret.getMetadata());
@@ -144,8 +144,8 @@ class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
assumeTrue(secret.getTtl() == 12345);
String secretJson3 = assertDoesNotThrow(() -> objectMapper.writeValueAsString(secret), "Serialization failed");
secret2 = assertDoesNotThrow(
() -> objectMapper.readValue(commaSeparatedToList(secretJson3), AppRoleSecret.class),
"Deserialization failed"
() -> objectMapper.readValue(commaSeparatedToList(secretJson3), AppRoleSecret.class),
"Deserialization failed"
);
assertEquals(secret2.getId(), secret.getId());
assertEquals(secret2.getMetadata(), secret.getMetadata());
@@ -159,9 +159,9 @@ class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
// Those fields should be deserialized from JSON though.
String secretJson4 = "{\"secret_id\":\"abc123\",\"metadata\":{\"number\":1337,\"foo\":\"bar\"}," +
"\"cidr_list\":[\"203.0.113.0/24\",\"198.51.100.0/24\"],\"secret_id_accessor\":\"TEST_ACCESSOR\"," +
"\"creation_time\":\"TEST_CREATION\",\"expiration_time\":\"TEST_EXPIRATION\"," +
"\"last_updated_time\":\"TEST_LASTUPDATE\",\"secret_id_num_uses\":678,\"secret_id_ttl\":12345}";
"\"cidr_list\":[\"203.0.113.0/24\",\"198.51.100.0/24\"],\"secret_id_accessor\":\"TEST_ACCESSOR\"," +
"\"creation_time\":\"TEST_CREATION\",\"expiration_time\":\"TEST_EXPIRATION\"," +
"\"last_updated_time\":\"TEST_LASTUPDATE\",\"secret_id_num_uses\":678,\"secret_id_ttl\":12345}";
secret2 = assertDoesNotThrow(() -> objectMapper.readValue(secretJson4, AppRoleSecret.class), "Deserialization failed");
assertEquals("TEST_ACCESSOR", secret2.getAccessor());
assertEquals("TEST_CREATION", secret2.getCreationTime());
@@ -181,6 +181,6 @@ class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
private static String commaSeparatedToList(String json) {
return json.replaceAll("\"cidr_list\":\"([^\"]*)\"", "\"cidr_list\":[$1]")
.replaceAll("(\\d+\\.\\d+\\.\\d+\\.\\d+/\\d+)", "\"$1\"");
.replaceAll("(\\d+\\.\\d+\\.\\d+\\.\\d+/\\d+)", "\"$1\"");
}
}

View File

@@ -42,18 +42,18 @@ class AppRoleTest extends AbstractModelTest<AppRole> {
private static final String POLICY = "policy";
private static final String POLICY_2 = "policy2";
private static final Integer SECRET_ID_NUM_USES = 10;
private static final Integer SECRET_ID_TTL = 7200;
private static final Long SECRET_ID_TTL = 7200L;
private static final Boolean LOCAL_SECRET_IDS = false;
private static final Integer TOKEN_TTL = 4800;
private static final Integer TOKEN_MAX_TTL = 9600;
private static final Integer TOKEN_EXPLICIT_MAX_TTL = 14400;
private static final Long TOKEN_TTL = 4800L;
private static final Long TOKEN_MAX_TTL = 9600L;
private static final Long TOKEN_EXPLICIT_MAX_TTL = 14400L;
private static final Boolean TOKEN_NO_DEFAULT_POLICY = false;
private static final Integer TOKEN_NUM_USES = 42;
private static final Integer TOKEN_PERIOD = 1234;
private static final Token.Type TOKEN_TYPE = Token.Type.DEFAULT_SERVICE;
private static final String JSON_MIN = "{\"role_name\":\"" + NAME + "\"}";
private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"secret_id_bound_cidrs\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"local_secret_ids\":%s,\"token_ttl\":%d,\"token_max_ttl\":%d,\"token_policies\":\"%s\",\"token_bound_cidrs\":\"%s\",\"token_explicit_max_ttl\":%d,\"token_no_default_policy\":%s,\"token_num_uses\":%d,\"token_period\":%d,\"token_type\":\"%s\"}",
NAME, ID, BIND_SECRET_ID, CIDR_1, SECRET_ID_NUM_USES, SECRET_ID_TTL, LOCAL_SECRET_IDS, TOKEN_TTL, TOKEN_MAX_TTL, POLICY, CIDR_1, TOKEN_EXPLICIT_MAX_TTL, TOKEN_NO_DEFAULT_POLICY, TOKEN_NUM_USES, TOKEN_PERIOD, TOKEN_TYPE.value());
NAME, ID, BIND_SECRET_ID, CIDR_1, SECRET_ID_NUM_USES, SECRET_ID_TTL, LOCAL_SECRET_IDS, TOKEN_TTL, TOKEN_MAX_TTL, POLICY, CIDR_1, TOKEN_EXPLICIT_MAX_TTL, TOKEN_NO_DEFAULT_POLICY, TOKEN_NUM_USES, TOKEN_PERIOD, TOKEN_TYPE.value());
AppRoleTest() {
super(AppRole.class);
@@ -62,22 +62,22 @@ class AppRoleTest extends AbstractModelTest<AppRole> {
@Override
protected AppRole createFull() {
return AppRole.builder(NAME)
.withId(ID)
.withBindSecretID(BIND_SECRET_ID)
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withTokenPolicies(POLICIES)
.withSecretIdNumUses(SECRET_ID_NUM_USES)
.withSecretIdTtl(SECRET_ID_TTL)
.withLocalSecretIds(LOCAL_SECRET_IDS)
.withTokenTtl(TOKEN_TTL)
.withTokenMaxTtl(TOKEN_MAX_TTL)
.withTokenBoundCidrs(BOUND_CIDR_LIST)
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
.withId(ID)
.withBindSecretID(BIND_SECRET_ID)
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withTokenPolicies(POLICIES)
.withSecretIdNumUses(SECRET_ID_NUM_USES)
.withSecretIdTtl(SECRET_ID_TTL)
.withLocalSecretIds(LOCAL_SECRET_IDS)
.withTokenTtl(TOKEN_TTL)
.withTokenMaxTtl(TOKEN_MAX_TTL)
.withTokenBoundCidrs(BOUND_CIDR_LIST)
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
}
@BeforeAll
@@ -159,11 +159,11 @@ class AppRoleTest extends AbstractModelTest<AppRole> {
assertEquals(1, role.getTokenBoundCidrs().size());
assertEquals(CIDR_2, role.getTokenBoundCidrs().get(0));
role = AppRole.builder(NAME)
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withSecretBoundCidr(CIDR_2)
.withTokenBoundCidrs(BOUND_CIDR_LIST)
.withTokenBoundCidr(CIDR_2)
.build();
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withSecretBoundCidr(CIDR_2)
.withTokenBoundCidrs(BOUND_CIDR_LIST)
.withTokenBoundCidr(CIDR_2)
.build();
assertEquals(2, role.getSecretIdBoundCidrs().size());
assertTrue(role.getSecretIdBoundCidrs().containsAll(List.of(CIDR_1, CIDR_2)));
assertEquals(2, role.getTokenBoundCidrs().size());
@@ -174,9 +174,9 @@ class AppRoleTest extends AbstractModelTest<AppRole> {
assertEquals(1, role.getTokenPolicies().size());
assertEquals(POLICY_2, role.getTokenPolicies().get(0));
role = AppRole.builder(NAME)
.withTokenPolicies(POLICIES)
.withTokenPolicy(POLICY_2)
.build();
.withTokenPolicies(POLICIES)
.withTokenPolicy(POLICY_2)
.build();
assertEquals(2, role.getTokenPolicies().size());
assertTrue(role.getTokenPolicies().containsAll(List.of(POLICY, POLICY_2)));
}

View File

@@ -59,28 +59,28 @@ class TokenRoleTest extends AbstractModelTest<TokenRole> {
private static final String TOKEN_BOUND_CIDR_2 = "198.51.100.0/24";
private static final String TOKEN_BOUND_CIDR_3 = "203.0.113.0/24";
private static final List<String> TOKEN_BOUND_CIDRS = Arrays.asList(TOKEN_BOUND_CIDR_2, TOKEN_BOUND_CIDR_1);
private static final Integer TOKEN_EXPLICIT_MAX_TTL = 1234;
private static final Long TOKEN_EXPLICIT_MAX_TTL = 1234L;
private static final Boolean TOKEN_NO_DEFAULT_POLICY = false;
private static final Integer TOKEN_NUM_USES = 5;
private static final Integer TOKEN_PERIOD = 2345;
private static final Token.Type TOKEN_TYPE = Token.Type.SERVICE;
private static final String JSON_FULL = "{" +
"\"name\":\"" + NAME + "\"," +
"\"allowed_policies\":[\"" + ALLOWED_POLICY_1 + "\",\"" + ALLOWED_POLICY_2 + "\",\"" + ALLOWED_POLICY_3 + "\"]," +
"\"allowed_policies_glob\":[\"" + ALLOWED_POLICY_GLOB_1 + "\",\"" + ALLOWED_POLICY_GLOB_2 + "\",\"" + ALLOWED_POLICY_GLOB_3 + "\"]," +
"\"disallowed_policies\":[\"" + DISALLOWED_POLICY_1 + "\",\"" + DISALLOWED_POLICY_2 + "\",\"" + DISALLOWED_POLICY_3 + "\"]," +
"\"disallowed_policies_glob\":[\"" + DISALLOWED_POLICY_GLOB_1 + "\",\"" + DISALLOWED_POLICY_GLOB_2 + "\",\"" + DISALLOWED_POLICY_GLOB_3 + "\"]," +
"\"orphan\":" + ORPHAN + "," +
"\"renewable\":" + RENEWABLE + "," +
"\"path_suffix\":\"" + PATH_SUFFIX + "\"," +
"\"allowed_entity_aliases\":[\"" + ALLOWED_ENTITY_ALIAS_1 + "\",\"" + ALLOWED_ENTITY_ALIAS_3 + "\",\"" + ALLOWED_ENTITY_ALIAS_2 + "\"]," +
"\"token_bound_cidrs\":[\"" + TOKEN_BOUND_CIDR_3 + "\",\"" + TOKEN_BOUND_CIDR_2 + "\",\"" + TOKEN_BOUND_CIDR_1 + "\"]," +
"\"token_explicit_max_ttl\":" + TOKEN_EXPLICIT_MAX_TTL + "," +
"\"token_no_default_policy\":" + TOKEN_NO_DEFAULT_POLICY + "," +
"\"token_num_uses\":" + TOKEN_NUM_USES + "," +
"\"token_period\":" + TOKEN_PERIOD + "," +
"\"token_type\":\"" + TOKEN_TYPE.value() + "\"}";
"\"name\":\"" + NAME + "\"," +
"\"allowed_policies\":[\"" + ALLOWED_POLICY_1 + "\",\"" + ALLOWED_POLICY_2 + "\",\"" + ALLOWED_POLICY_3 + "\"]," +
"\"allowed_policies_glob\":[\"" + ALLOWED_POLICY_GLOB_1 + "\",\"" + ALLOWED_POLICY_GLOB_2 + "\",\"" + ALLOWED_POLICY_GLOB_3 + "\"]," +
"\"disallowed_policies\":[\"" + DISALLOWED_POLICY_1 + "\",\"" + DISALLOWED_POLICY_2 + "\",\"" + DISALLOWED_POLICY_3 + "\"]," +
"\"disallowed_policies_glob\":[\"" + DISALLOWED_POLICY_GLOB_1 + "\",\"" + DISALLOWED_POLICY_GLOB_2 + "\",\"" + DISALLOWED_POLICY_GLOB_3 + "\"]," +
"\"orphan\":" + ORPHAN + "," +
"\"renewable\":" + RENEWABLE + "," +
"\"path_suffix\":\"" + PATH_SUFFIX + "\"," +
"\"allowed_entity_aliases\":[\"" + ALLOWED_ENTITY_ALIAS_1 + "\",\"" + ALLOWED_ENTITY_ALIAS_3 + "\",\"" + ALLOWED_ENTITY_ALIAS_2 + "\"]," +
"\"token_bound_cidrs\":[\"" + TOKEN_BOUND_CIDR_3 + "\",\"" + TOKEN_BOUND_CIDR_2 + "\",\"" + TOKEN_BOUND_CIDR_1 + "\"]," +
"\"token_explicit_max_ttl\":" + TOKEN_EXPLICIT_MAX_TTL + "," +
"\"token_no_default_policy\":" + TOKEN_NO_DEFAULT_POLICY + "," +
"\"token_num_uses\":" + TOKEN_NUM_USES + "," +
"\"token_period\":" + TOKEN_PERIOD + "," +
"\"token_type\":\"" + TOKEN_TYPE.value() + "\"}";
TokenRoleTest() {
super(TokenRole.class);
@@ -89,28 +89,28 @@ class TokenRoleTest extends AbstractModelTest<TokenRole> {
@Override
protected TokenRole createFull() {
return TokenRole.builder()
.forName(NAME)
.withAllowedPolicies(ALLOWED_POLICIES)
.withAllowedPolicy(ALLOWED_POLICY_3)
.withAllowedPolicyGlob(ALLOWED_POLICY_GLOB_1)
.withAllowedPoliciesGlob(ALLOWED_POLICIES_GLOB)
.withDisallowedPolicy(DISALLOWED_POLICY_1)
.withDisallowedPolicies(DISALLOWED_POLICIES)
.withDisallowedPoliciesGlob(DISALLOWED_POLICIES_GLOB)
.withDisallowedPolicyGlob(DISALLOWED_POLICY_GLOB_3)
.orphan(ORPHAN)
.renewable(RENEWABLE)
.withPathSuffix(PATH_SUFFIX)
.withAllowedEntityAliases(ALLOWED_ENTITY_ALIASES)
.withAllowedEntityAlias(ALLOWED_ENTITY_ALIAS_2)
.withTokenBoundCidr(TOKEN_BOUND_CIDR_3)
.withTokenBoundCidrs(TOKEN_BOUND_CIDRS)
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
.forName(NAME)
.withAllowedPolicies(ALLOWED_POLICIES)
.withAllowedPolicy(ALLOWED_POLICY_3)
.withAllowedPolicyGlob(ALLOWED_POLICY_GLOB_1)
.withAllowedPoliciesGlob(ALLOWED_POLICIES_GLOB)
.withDisallowedPolicy(DISALLOWED_POLICY_1)
.withDisallowedPolicies(DISALLOWED_POLICIES)
.withDisallowedPoliciesGlob(DISALLOWED_POLICIES_GLOB)
.withDisallowedPolicyGlob(DISALLOWED_POLICY_GLOB_3)
.orphan(ORPHAN)
.renewable(RENEWABLE)
.withPathSuffix(PATH_SUFFIX)
.withAllowedEntityAliases(ALLOWED_ENTITY_ALIASES)
.withAllowedEntityAlias(ALLOWED_ENTITY_ALIAS_2)
.withTokenBoundCidr(TOKEN_BOUND_CIDR_3)
.withTokenBoundCidrs(TOKEN_BOUND_CIDRS)
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
}
/**
@@ -141,24 +141,24 @@ class TokenRoleTest extends AbstractModelTest<TokenRole> {
@Test
void buildNullTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder()
.forName(null)
.withAllowedPolicies(null)
.withAllowedPolicy(null)
.withDisallowedPolicy(null)
.withDisallowedPolicies(null)
.orphan(null)
.renewable(null)
.withPathSuffix(null)
.withAllowedEntityAliases(null)
.withAllowedEntityAlias(null)
.withTokenBoundCidr(null)
.withTokenBoundCidrs(null)
.withTokenExplicitMaxTtl(null)
.withTokenNoDefaultPolicy(null)
.withTokenNumUses(null)
.withTokenPeriod(null)
.withTokenType(null)
.build();
.forName(null)
.withAllowedPolicies(null)
.withAllowedPolicy(null)
.withDisallowedPolicy(null)
.withDisallowedPolicies(null)
.orphan(null)
.renewable(null)
.withPathSuffix(null)
.withAllowedEntityAliases(null)
.withAllowedEntityAlias(null)
.withTokenBoundCidr(null)
.withTokenBoundCidrs(null)
.withTokenExplicitMaxTtl(null)
.withTokenNoDefaultPolicy(null)
.withTokenNumUses(null)
.withTokenPeriod(null)
.withTokenType(null)
.build();
assertNull(role.getAllowedPolicies());
assertNull(role.getDisallowedPolicies());

View File

@@ -35,8 +35,8 @@ class TokenTest extends AbstractModelTest<Token> {
private static final String DISPLAY_NAME = "display-name";
private static final Boolean NO_PARENT = false;
private static final Boolean NO_DEFAULT_POLICY = false;
private static final Integer TTL = 123;
private static final Integer EXPLICIT_MAX_TTL = 456;
private static final Long TTL = 123L;
private static final Long EXPLICIT_MAX_TTL = 456L;
private static final Integer NUM_USES = 4;
private static final List<String> POLICIES = new ArrayList<>();
private static final String POLICY = "policy";
@@ -59,20 +59,20 @@ class TokenTest extends AbstractModelTest<Token> {
@Override
protected Token createFull() {
return Token.builder()
.withId(ID)
.withType(Token.Type.SERVICE)
.withDisplayName(DISPLAY_NAME)
.withNoParent(NO_PARENT)
.withNoDefaultPolicy(NO_DEFAULT_POLICY)
.withTtl(TTL)
.withExplicitMaxTtl(EXPLICIT_MAX_TTL)
.withNumUses(NUM_USES)
.withPolicies(POLICIES)
.withMeta(META)
.withRenewable(RENEWABLE)
.withPeriod(PERIOD)
.withEntityAlias(ENTITY_ALIAS)
.build();
.withId(ID)
.withType(Token.Type.SERVICE)
.withDisplayName(DISPLAY_NAME)
.withNoParent(NO_PARENT)
.withNoDefaultPolicy(NO_DEFAULT_POLICY)
.withTtl(TTL)
.withExplicitMaxTtl(EXPLICIT_MAX_TTL)
.withNumUses(NUM_USES)
.withPolicies(POLICIES)
.withMeta(META)
.withRenewable(RENEWABLE)
.withPeriod(PERIOD)
.withEntityAlias(ENTITY_ALIAS)
.build();
}
@BeforeAll
@@ -159,9 +159,9 @@ class TokenTest extends AbstractModelTest<Token> {
assertEquals(1, token.getPolicies().size());
assertEquals(List.of(POLICY_2), token.getPolicies());
token = Token.builder()
.withPolicies(POLICY, POLICY_2)
.withPolicy(POLICY_3)
.build();
.withPolicies(POLICY, POLICY_2)
.withPolicy(POLICY_3)
.build();
assertEquals(3, token.getPolicies().size());
assertTrue(token.getPolicies().containsAll(List.of(POLICY, POLICY_2, POLICY_3)));
@@ -171,9 +171,9 @@ class TokenTest extends AbstractModelTest<Token> {
assertEquals(Set.of(META_KEY_2), token.getMeta().keySet());
assertEquals(META_VALUE_2, token.getMeta().get(META_KEY_2));
token = Token.builder()
.withMeta(META)
.withMeta(META_KEY_2, META_VALUE_2)
.build();
.withMeta(META)
.withMeta(META_KEY_2, META_VALUE_2)
.build();
assertEquals(2, token.getMeta().size());
assertEquals(META_VALUE, token.getMeta().get(META_KEY));
assertEquals(META_VALUE_2, token.getMeta().get(META_KEY_2));

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import de.stklcode.jvault.connector.model.AppRole;
import org.junit.jupiter.api.Test;
@@ -32,34 +31,34 @@ import static org.junit.jupiter.api.Assertions.*;
* @since 0.6.2
*/
class AppRoleResponseTest extends AbstractModelTest<AppRoleResponse> {
private static final Integer ROLE_TOKEN_TTL = 1200;
private static final Integer ROLE_TOKEN_MAX_TTL = 1800;
private static final Integer ROLE_SECRET_TTL = 600;
private static final Long ROLE_TOKEN_TTL = 1200L;
private static final Long ROLE_TOKEN_MAX_TTL = 1800L;
private static final Long ROLE_SECRET_TTL = 600L;
private static final Integer ROLE_SECRET_NUM_USES = 40;
private static final String ROLE_POLICY = "default";
private static final Integer ROLE_PERIOD = 0;
private static final Boolean ROLE_BIND_SECRET = true;
private static final String RES_JSON = "{\n" +
" \"auth\": null,\n" +
" \"warnings\": null,\n" +
" \"wrap_info\": null,\n" +
" \"data\": {\n" +
" \"token_ttl\": " + ROLE_TOKEN_TTL + ",\n" +
" \"token_max_ttl\": " + ROLE_TOKEN_MAX_TTL + ",\n" +
" \"secret_id_ttl\": " + ROLE_SECRET_TTL + ",\n" +
" \"secret_id_num_uses\": " + ROLE_SECRET_NUM_USES + ",\n" +
" \"token_policies\": [\n" +
" \"" + ROLE_POLICY + "\"\n" +
" ],\n" +
" \"token_period\": " + ROLE_PERIOD + ",\n" +
" \"bind_secret_id\": " + ROLE_BIND_SECRET + ",\n" +
" \"bound_cidr_list\": \"\"\n" +
" },\n" +
" \"lease_duration\": 0,\n" +
" \"renewable\": false,\n" +
" \"lease_id\": \"\"\n" +
"}";
" \"auth\": null,\n" +
" \"warnings\": null,\n" +
" \"wrap_info\": null,\n" +
" \"data\": {\n" +
" \"token_ttl\": " + ROLE_TOKEN_TTL + ",\n" +
" \"token_max_ttl\": " + ROLE_TOKEN_MAX_TTL + ",\n" +
" \"secret_id_ttl\": " + ROLE_SECRET_TTL + ",\n" +
" \"secret_id_num_uses\": " + ROLE_SECRET_NUM_USES + ",\n" +
" \"token_policies\": [\n" +
" \"" + ROLE_POLICY + "\"\n" +
" ],\n" +
" \"token_period\": " + ROLE_PERIOD + ",\n" +
" \"bind_secret_id\": " + ROLE_BIND_SECRET + ",\n" +
" \"bound_cidr_list\": \"\"\n" +
" },\n" +
" \"lease_duration\": 0,\n" +
" \"renewable\": false,\n" +
" \"lease_id\": \"\"\n" +
"}";
AppRoleResponseTest() {
super(AppRoleResponse.class);
@@ -67,12 +66,10 @@ class AppRoleResponseTest extends AbstractModelTest<AppRoleResponse> {
@Override
protected AppRoleResponse createFull() {
try {
return objectMapper.readValue(RES_JSON, AppRoleResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, AppRoleResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -91,8 +88,8 @@ class AppRoleResponseTest extends AbstractModelTest<AppRoleResponse> {
@Test
void jsonRoundtrip() {
AppRoleResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, AppRoleResponse.class),
"AuthResponse deserialization failed"
() -> objectMapper.readValue(RES_JSON, AppRoleResponse.class),
"AuthResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
// Extract role data.

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import de.stklcode.jvault.connector.model.AuthBackend;
import de.stklcode.jvault.connector.model.response.embedded.AuthMethod;
@@ -45,44 +44,44 @@ class AuthMethodsResponseTest extends AbstractModelTest<AuthMethodsResponse> {
private static final String TK_UUID = "32ea9681-6bd6-6cec-eec3-d11260ba9741";
private static final String TK_ACCESSOR = "auth_token_ac0dd95a";
private static final String TK_DESCR = "token based credentials";
private static final Integer TK_LEASE_TTL = 0;
private static final Long TK_LEASE_TTL = 0L;
private static final Boolean TK_FORCE_NO_CACHE = false;
private static final Integer TK_MAX_LEASE_TTL = 0;
private static final Long TK_MAX_LEASE_TTL = 0L;
private static final String TK_TOKEN_TYPE = "default-service";
private static final String TK_RUNNING_PLUGIN_VERSION = "v1.15.3+builtin.vault";
private static final String RES_JSON = "{\n" +
" \"data\": {" +
" \"" + GH_PATH + "\": {\n" +
" \"uuid\": \"" + GH_UUID + "\",\n" +
" \"type\": \"" + GH_TYPE + "\",\n" +
" \"accessor\": \"" + GH_ACCESSOR + "\",\n" +
" \"description\": \"" + GH_DESCR + "\",\n" +
" \"external_entropy_access\": false,\n" +
" \"local\": false,\n" +
" \"seal_wrap\": false\n" +
" },\n" +
" \"" + TK_PATH + "\": {\n" +
" \"config\": {\n" +
" \"default_lease_ttl\": " + TK_LEASE_TTL + ",\n" +
" \"force_no_cache\": " + TK_FORCE_NO_CACHE + ",\n" +
" \"max_lease_ttl\": " + TK_MAX_LEASE_TTL + ",\n" +
" \"token_type\": \"" + TK_TOKEN_TYPE + "\"\n" +
" },\n" +
" \"description\": \"" + TK_DESCR + "\",\n" +
" \"options\": null,\n" +
" \"plugin_version\": \"\",\n" +
" \"running_plugin_version\": \"" + TK_RUNNING_PLUGIN_VERSION + "\",\n" +
" \"running_sha256\": \"\",\n" +
" \"type\": \"" + TK_TYPE + "\",\n" +
" \"uuid\": \"" + TK_UUID + "\",\n" +
" \"accessor\": \"" + TK_ACCESSOR + "\",\n" +
" \"external_entropy_access\": false,\n" +
" \"local\": true,\n" +
" \"seal_wrap\": false\n" +
" }\n" +
" }\n" +
"}";
" \"data\": {" +
" \"" + GH_PATH + "\": {\n" +
" \"uuid\": \"" + GH_UUID + "\",\n" +
" \"type\": \"" + GH_TYPE + "\",\n" +
" \"accessor\": \"" + GH_ACCESSOR + "\",\n" +
" \"description\": \"" + GH_DESCR + "\",\n" +
" \"external_entropy_access\": false,\n" +
" \"local\": false,\n" +
" \"seal_wrap\": false\n" +
" },\n" +
" \"" + TK_PATH + "\": {\n" +
" \"config\": {\n" +
" \"default_lease_ttl\": " + TK_LEASE_TTL + ",\n" +
" \"force_no_cache\": " + TK_FORCE_NO_CACHE + ",\n" +
" \"max_lease_ttl\": " + TK_MAX_LEASE_TTL + ",\n" +
" \"token_type\": \"" + TK_TOKEN_TYPE + "\"\n" +
" },\n" +
" \"description\": \"" + TK_DESCR + "\",\n" +
" \"options\": null,\n" +
" \"plugin_version\": \"\",\n" +
" \"running_plugin_version\": \"" + TK_RUNNING_PLUGIN_VERSION + "\",\n" +
" \"running_sha256\": \"\",\n" +
" \"type\": \"" + TK_TYPE + "\",\n" +
" \"uuid\": \"" + TK_UUID + "\",\n" +
" \"accessor\": \"" + TK_ACCESSOR + "\",\n" +
" \"external_entropy_access\": false,\n" +
" \"local\": true,\n" +
" \"seal_wrap\": false\n" +
" }\n" +
" }\n" +
"}";
AuthMethodsResponseTest() {
super(AuthMethodsResponse.class);
@@ -90,12 +89,10 @@ class AuthMethodsResponseTest extends AbstractModelTest<AuthMethodsResponse> {
@Override
protected AuthMethodsResponse createFull() {
try {
return objectMapper.readValue(RES_JSON, AuthMethodsResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, AuthMethodsResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -114,8 +111,8 @@ class AuthMethodsResponseTest extends AbstractModelTest<AuthMethodsResponse> {
@Test
void jsonRoundtrip() {
AuthMethodsResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, AuthMethodsResponse.class),
"AuthResponse deserialization failed"
() -> objectMapper.readValue(RES_JSON, AuthMethodsResponse.class),
"AuthResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
// Extract auth data.

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import de.stklcode.jvault.connector.model.response.embedded.AuthData;
import de.stklcode.jvault.connector.model.response.embedded.MfaConstraintAny;
@@ -101,12 +100,10 @@ class AuthResponseTest extends AbstractModelTest<AuthResponse> {
@Override
protected AuthResponse createFull() {
try {
return objectMapper.readValue(RES_JSON, AuthResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, AuthResponse.class),
"Creation of full model instance failed"
);
}
@Test
@@ -122,8 +119,8 @@ class AuthResponseTest extends AbstractModelTest<AuthResponse> {
@Test
void jsonRoundtrip() {
AuthResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, AuthResponse.class),
"AuthResponse deserialization failed"
() -> objectMapper.readValue(RES_JSON, AuthResponse.class),
"AuthResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
// Extract auth data.

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -32,16 +31,16 @@ class CredentialsResponseTest extends AbstractModelTest<CredentialsResponse> {
private static final String VAL_USER = "testUserName";
private static final String VAL_PASS = "5up3r5ecr3tP455";
private static final String JSON = "{\n" +
" \"request_id\": \"68315073-6658-e3ff-2da7-67939fb91bbd\",\n" +
" \"lease_id\": \"\",\n" +
" \"lease_duration\": 2764800,\n" +
" \"renewable\": false,\n" +
" \"data\": {\n" +
" \"username\": \"" + VAL_USER + "\",\n" +
" \"password\": \"" + VAL_PASS + "\"\n" +
" },\n" +
" \"warnings\": null\n" +
"}";
" \"request_id\": \"68315073-6658-e3ff-2da7-67939fb91bbd\",\n" +
" \"lease_id\": \"\",\n" +
" \"lease_duration\": 2764800,\n" +
" \"renewable\": false,\n" +
" \"data\": {\n" +
" \"username\": \"" + VAL_USER + "\",\n" +
" \"password\": \"" + VAL_PASS + "\"\n" +
" },\n" +
" \"warnings\": null\n" +
"}";
CredentialsResponseTest() {
super(CredentialsResponse.class);
@@ -49,12 +48,10 @@ class CredentialsResponseTest extends AbstractModelTest<CredentialsResponse> {
@Override
protected CredentialsResponse createFull() {
try {
return objectMapper.readValue(JSON, CredentialsResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(JSON, CredentialsResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -68,8 +65,8 @@ class CredentialsResponseTest extends AbstractModelTest<CredentialsResponse> {
assertNull(res.getPassword(), "Password not present in data map should not return anything");
res = assertDoesNotThrow(
() -> objectMapper.readValue(JSON, CredentialsResponse.class),
"Deserialization of CredentialsResponse failed"
() -> objectMapper.readValue(JSON, CredentialsResponse.class),
"Deserialization of CredentialsResponse failed"
);
assertEquals(VAL_USER, res.getUsername(), "Incorrect username");
assertEquals(VAL_PASS, res.getPassword(), "Incorrect password");

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -42,12 +41,10 @@ class ErrorResponseTest extends AbstractModelTest<ErrorResponse> {
@Override
protected ErrorResponse createFull() {
try {
return objectMapper.readValue(JSON, ErrorResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(JSON, ErrorResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -56,15 +53,15 @@ class ErrorResponseTest extends AbstractModelTest<ErrorResponse> {
@Test
void jsonRoundtrip() {
ErrorResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(JSON, ErrorResponse.class),
"ErrorResponse deserialization failed"
() -> objectMapper.readValue(JSON, ErrorResponse.class),
"ErrorResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertEquals(List.of(ERROR_1, ERROR_2), res.getErrors(), "Unexpected error messages");
assertEquals(
JSON,
assertDoesNotThrow(() -> objectMapper.writeValueAsString(res), "ErrorResponse serialization failed"),
"Unexpected JSON string after serialization"
JSON,
assertDoesNotThrow(() -> objectMapper.writeValueAsString(res), "ErrorResponse serialization failed"),
"Unexpected JSON string after serialization"
);
}
@@ -72,14 +69,14 @@ class ErrorResponseTest extends AbstractModelTest<ErrorResponse> {
@Test
void testToString() {
ErrorResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(JSON, ErrorResponse.class),
"ErrorResponse deserialization failed"
() -> objectMapper.readValue(JSON, ErrorResponse.class),
"ErrorResponse deserialization failed"
);
assertEquals(ERROR_1, res.toString());
res = assertDoesNotThrow(
() -> objectMapper.readValue(JSON_EMPTY, ErrorResponse.class),
"ErrorResponse deserialization failed with empty list"
() -> objectMapper.readValue(JSON_EMPTY, ErrorResponse.class),
"ErrorResponse deserialization failed with empty list"
);
assertEquals("error response", res.toString());

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -45,21 +44,21 @@ class HealthResponseTest extends AbstractModelTest<HealthResponse> {
private static final Boolean ENTERPRISE = false;
private static final String RES_JSON = "{\n" +
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
" \"version\": \"" + VERSION + "\",\n" +
" \"server_time_utc\": " + SERVER_TIME_UTC + ",\n" +
" \"standby\": " + STANDBY + ",\n" +
" \"sealed\": " + SEALED + ",\n" +
" \"initialized\": " + INITIALIZED + ",\n" +
" \"replication_performance_mode\": \"" + REPL_PERF_MODE + "\",\n" +
" \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" +
" \"performance_standby\": " + PERF_STANDBY + ",\n" +
" \"echo_duration_ms\": " + ECHO_DURATION + ",\n" +
" \"clock_skew_ms\": " + CLOCK_SKEW + ",\n" +
" \"replication_primary_canary_age_ms\": " + REPL_PRIM_CANARY_AGE + ",\n" +
" \"enterprise\": " + ENTERPRISE + "\n" +
"}";
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
" \"version\": \"" + VERSION + "\",\n" +
" \"server_time_utc\": " + SERVER_TIME_UTC + ",\n" +
" \"standby\": " + STANDBY + ",\n" +
" \"sealed\": " + SEALED + ",\n" +
" \"initialized\": " + INITIALIZED + ",\n" +
" \"replication_performance_mode\": \"" + REPL_PERF_MODE + "\",\n" +
" \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" +
" \"performance_standby\": " + PERF_STANDBY + ",\n" +
" \"echo_duration_ms\": " + ECHO_DURATION + ",\n" +
" \"clock_skew_ms\": " + CLOCK_SKEW + ",\n" +
" \"replication_primary_canary_age_ms\": " + REPL_PRIM_CANARY_AGE + ",\n" +
" \"enterprise\": " + ENTERPRISE + "\n" +
"}";
HealthResponseTest() {
super(HealthResponse.class);
@@ -67,12 +66,10 @@ class HealthResponseTest extends AbstractModelTest<HealthResponse> {
@Override
protected HealthResponse createFull() {
try {
return objectMapper.readValue(RES_JSON, HealthResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, HealthResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -81,8 +78,8 @@ class HealthResponseTest extends AbstractModelTest<HealthResponse> {
@Test
void jsonRoundtrip() {
HealthResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, HealthResponse.class),
"Health deserialization failed"
() -> objectMapper.readValue(RES_JSON, HealthResponse.class),
"Health deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertEquals(CLUSTER_ID, res.getClusterID(), "Incorrect cluster ID");

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -38,12 +37,10 @@ class HelpResponseTest extends AbstractModelTest<HelpResponse> {
@Override
protected HelpResponse createFull() {
try {
return objectMapper.readValue(JSON, HelpResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(JSON, HelpResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -52,15 +49,15 @@ class HelpResponseTest extends AbstractModelTest<HelpResponse> {
@Test
void jsonRoundtrip() {
HelpResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(JSON, HelpResponse.class),
"HelpResponse deserialization failed"
() -> objectMapper.readValue(JSON, HelpResponse.class),
"HelpResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertEquals(HELP, res.getHelp(), "Unexpected help text");
assertEquals(
JSON,
assertDoesNotThrow(() -> objectMapper.writeValueAsString(res), "HelpResponse serialization failed"),
"Unexpected JSON string after serialization"
JSON,
assertDoesNotThrow(() -> objectMapper.writeValueAsString(res), "HelpResponse serialization failed"),
"Unexpected JSON string after serialization"
);
}
}

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -47,47 +46,47 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
private static final String CUSTOM_META_VAL = "bar";
private static final String SECRET_JSON_V2 = "{\n" +
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
" \"data\": {\n" +
" \"data\": {\n" +
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
" },\n" +
" \"metadata\": {\n" +
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
" \"custom_metadata\": null,\n" +
" \"deletion_time\": \"\",\n" +
" \"destroyed\": false,\n" +
" \"version\": 1\n" +
" }\n" +
" },\n" +
" \"warnings\": " + SECRET_WARNINGS + "\n" +
"}";
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
" \"data\": {\n" +
" \"data\": {\n" +
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
" },\n" +
" \"metadata\": {\n" +
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
" \"custom_metadata\": null,\n" +
" \"deletion_time\": \"\",\n" +
" \"destroyed\": false,\n" +
" \"version\": 1\n" +
" }\n" +
" },\n" +
" \"warnings\": " + SECRET_WARNINGS + "\n" +
"}";
private static final String SECRET_JSON_V2_2 = "{\n" +
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
" \"data\": {\n" +
" \"data\": {\n" +
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
" },\n" +
" \"metadata\": {\n" +
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
" \"custom_metadata\": {" +
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
" },\n" +
" \"deletion_time\": \"" + SECRET_META_DELETED + "\",\n" +
" \"destroyed\": true,\n" +
" \"version\": 2\n" +
" }\n" +
" },\n" +
" \"warnings\": " + SECRET_WARNINGS + "\n" +
"}";
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
" \"data\": {\n" +
" \"data\": {\n" +
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
" },\n" +
" \"metadata\": {\n" +
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
" \"custom_metadata\": {" +
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
" },\n" +
" \"deletion_time\": \"" + SECRET_META_DELETED + "\",\n" +
" \"destroyed\": true,\n" +
" \"version\": 2\n" +
" }\n" +
" },\n" +
" \"warnings\": " + SECRET_WARNINGS + "\n" +
"}";
MetaSecretResponseTest() {
super(MetaSecretResponse.class);
@@ -95,12 +94,10 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
@Override
protected MetaSecretResponse createFull() {
try {
return objectMapper.readValue(SECRET_JSON_V2, MetaSecretResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(SECRET_JSON_V2, MetaSecretResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -110,8 +107,8 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
void jsonRoundtrip() {
// KV v2 secret.
MetaSecretResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(SECRET_JSON_V2, MetaSecretResponse.class),
"SecretResponse deserialization failed"
() -> objectMapper.readValue(SECRET_JSON_V2, MetaSecretResponse.class),
"SecretResponse deserialization failed"
);
assertSecretData(res);
assertNotNull(res.getMetadata(), "SecretResponse does not contain metadata");
@@ -123,8 +120,8 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
// Deleted KV v2 secret.
res = assertDoesNotThrow(
() -> objectMapper.readValue(SECRET_JSON_V2_2, MetaSecretResponse.class),
"SecretResponse deserialization failed"
() -> objectMapper.readValue(SECRET_JSON_V2_2, MetaSecretResponse.class),
"SecretResponse deserialization failed"
);
assertSecretData(res);
assertNotNull(res.getMetadata(), "SecretResponse does not contain metadata");

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -43,36 +42,36 @@ class MetadataResponseTest extends AbstractModelTest<MetadataResponse> {
private static final String DELETE_VERSION_AFTER = "0s";
private static final String META_JSON = "{\n" +
" \"data\": {\n" +
" \"cas_required\": " + CAS_REQUIRED + ",\n" +
" \"created_time\": \"" + V1_TIME + "\",\n" +
" \"current_version\": " + CURRENT_VERSION + ",\n" +
" \"custom_metadata\": {" +
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
" },\n" +
" \"delete_version_after\": \"" + DELETE_VERSION_AFTER + "\"," +
" \"max_versions\": " + MAX_VERSIONS + ",\n" +
" \"oldest_version\": " + OLDEST_VERSION + ",\n" +
" \"updated_time\": \"" + V3_TIME + "\",\n" +
" \"versions\": {\n" +
" \"1\": {\n" +
" \"created_time\": \"" + V1_TIME + "\",\n" +
" \"deletion_time\": \"" + V2_TIME + "\",\n" +
" \"destroyed\": true\n" +
" },\n" +
" \"2\": {\n" +
" \"created_time\": \"" + V2_TIME + "\",\n" +
" \"deletion_time\": \"\",\n" +
" \"destroyed\": false\n" +
" },\n" +
" \"3\": {\n" +
" \"created_time\": \"" + V3_TIME + "\",\n" +
" \"deletion_time\": \"\",\n" +
" \"destroyed\": false\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
" \"data\": {\n" +
" \"cas_required\": " + CAS_REQUIRED + ",\n" +
" \"created_time\": \"" + V1_TIME + "\",\n" +
" \"current_version\": " + CURRENT_VERSION + ",\n" +
" \"custom_metadata\": {" +
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
" },\n" +
" \"delete_version_after\": \"" + DELETE_VERSION_AFTER + "\"," +
" \"max_versions\": " + MAX_VERSIONS + ",\n" +
" \"oldest_version\": " + OLDEST_VERSION + ",\n" +
" \"updated_time\": \"" + V3_TIME + "\",\n" +
" \"versions\": {\n" +
" \"1\": {\n" +
" \"created_time\": \"" + V1_TIME + "\",\n" +
" \"deletion_time\": \"" + V2_TIME + "\",\n" +
" \"destroyed\": true\n" +
" },\n" +
" \"2\": {\n" +
" \"created_time\": \"" + V2_TIME + "\",\n" +
" \"deletion_time\": \"\",\n" +
" \"destroyed\": false\n" +
" },\n" +
" \"3\": {\n" +
" \"created_time\": \"" + V3_TIME + "\",\n" +
" \"deletion_time\": \"\",\n" +
" \"destroyed\": false\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
MetadataResponseTest() {
super(MetadataResponse.class);
@@ -80,12 +79,10 @@ class MetadataResponseTest extends AbstractModelTest<MetadataResponse> {
@Override
protected MetadataResponse createFull() {
try {
return objectMapper.readValue(META_JSON, MetadataResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(META_JSON, MetadataResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -94,8 +91,8 @@ class MetadataResponseTest extends AbstractModelTest<MetadataResponse> {
@Test
void jsonRoundtrip() {
MetadataResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(META_JSON, MetadataResponse.class),
"MetadataResponse deserialization failed"
() -> objectMapper.readValue(META_JSON, MetadataResponse.class),
"MetadataResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertNotNull(res.getMetadata(), "Parsed metadata is NULL");

View File

@@ -17,7 +17,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -43,16 +42,16 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
private static final String SECRET_DATA_V2 = "world";
private static final List<String> SECRET_WARNINGS = null;
private static final String SECRET_JSON = "{\n" +
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
" \"data\": {\n" +
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
" },\n" +
" \"warnings\": " + SECRET_WARNINGS + "\n" +
"}";
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
" \"data\": {\n" +
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
" },\n" +
" \"warnings\": " + SECRET_WARNINGS + "\n" +
"}";
PlainSecretResponseTest() {
super(PlainSecretResponse.class);
@@ -60,12 +59,10 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
@Override
protected PlainSecretResponse createFull() {
try {
return objectMapper.readValue(SECRET_JSON, PlainSecretResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(SECRET_JSON, PlainSecretResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -74,8 +71,8 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
@Test
void jsonRoundtrip() {
SecretResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(SECRET_JSON, PlainSecretResponse.class),
"SecretResponse deserialization failed"
() -> objectMapper.readValue(SECRET_JSON, PlainSecretResponse.class),
"SecretResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
@@ -106,74 +103,74 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
final var complexVal = new ComplexType("val1", 678);
SecretResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(
"{\n" +
" \"request_id\": \"req-id\",\n" +
" \"lease_id\": \"lea-id\",\n" +
" \"lease_duration\": " + 123456 + ",\n" +
" \"renewable\": true,\n" +
" \"data\": {\n" +
" \"" + stringKey + "\": \"" + stringVal + "\",\n" +
" \"" + numberKey + "\": \"" + numberVal + "\",\n" +
" \"" + listKey + "\": [\"" + String.join("\", \"", listVal) + "\"],\n" +
" \"" + complexKey + "\": {" +
" \"field1\": \"" + complexVal.field1 + "\",\n" +
" \"field2\": " + complexVal.field2 + "\n" +
" },\n" +
" \"" + complexKey + "Json\": \"" + objectMapper.writeValueAsString(complexVal).replace("\"", "\\\"") + "\"\n" +
" }\n" +
"}",
PlainSecretResponse.class
),
"SecretResponse deserialization failed"
() -> objectMapper.readValue(
"{\n" +
" \"request_id\": \"req-id\",\n" +
" \"lease_id\": \"lea-id\",\n" +
" \"lease_duration\": " + 123456 + ",\n" +
" \"renewable\": true,\n" +
" \"data\": {\n" +
" \"" + stringKey + "\": \"" + stringVal + "\",\n" +
" \"" + numberKey + "\": \"" + numberVal + "\",\n" +
" \"" + listKey + "\": [\"" + String.join("\", \"", listVal) + "\"],\n" +
" \"" + complexKey + "\": {" +
" \"field1\": \"" + complexVal.field1 + "\",\n" +
" \"field2\": " + complexVal.field2 + "\n" +
" },\n" +
" \"" + complexKey + "Json\": \"" + objectMapper.writeValueAsString(complexVal).replace("\"", "\\\"") + "\"\n" +
" }\n" +
"}",
PlainSecretResponse.class
),
"SecretResponse deserialization failed"
);
assertEquals(stringVal, res.get(stringKey), "unexpected value for string (implicit)");
assertEquals(
stringVal,
assertDoesNotThrow(() -> res.get(stringKey, String.class), "getting string failed"),
"unexpected value for string (explicit)"
stringVal,
assertDoesNotThrow(() -> res.get(stringKey, String.class), "getting string failed"),
"unexpected value for string (explicit)"
);
assertEquals(String.valueOf(numberVal), res.get(numberKey), "unexpected value for number (implicit)");
assertEquals(
numberVal,
assertDoesNotThrow(() -> res.get(numberKey, Double.class), "getting number failed"),
"unexpected value for number (explicit)"
numberVal,
assertDoesNotThrow(() -> res.get(numberKey, Double.class), "getting number failed"),
"unexpected value for number (explicit)"
);
assertEquals(
String.valueOf(numberVal),
assertDoesNotThrow(() -> res.get(numberKey, String.class), "getting number as string failed"),
"unexpected value for number as string (explicit)"
String.valueOf(numberVal),
assertDoesNotThrow(() -> res.get(numberKey, String.class), "getting number as string failed"),
"unexpected value for number as string (explicit)"
);
assertEquals(listVal, res.get(listKey), "unexpected value for list (implicit)");
assertEquals(
listVal,
assertDoesNotThrow(() -> res.get(listKey, ArrayList.class), "getting list failed"),
"unexpected value for list (explicit)"
listVal,
assertDoesNotThrow(() -> res.get(listKey, ArrayList.class), "getting list failed"),
"unexpected value for list (explicit)"
);
assertEquals(complexVal.toMap(), res.get(complexKey), "unexpected value for complex type (implicit)");
assertEquals(
complexVal.toMap(),
assertDoesNotThrow(() -> res.get(complexKey, HashMap.class), "getting complex type as map failed"),
"unexpected value for complex type as map (explicit)"
complexVal.toMap(),
assertDoesNotThrow(() -> res.get(complexKey, HashMap.class), "getting complex type as map failed"),
"unexpected value for complex type as map (explicit)"
);
assertEquals(
complexVal,
assertDoesNotThrow(() -> res.get(complexKey, ComplexType.class), "getting complex type failed"),
"unexpected value for complex type (explicit)"
complexVal,
assertDoesNotThrow(() -> res.get(complexKey, ComplexType.class), "getting complex type failed"),
"unexpected value for complex type (explicit)"
);
assertThrows(
InvalidResponseException.class,
() -> res.get(complexKey, Integer.class),
"getting complex type as integer should fail"
InvalidResponseException.class,
() -> res.get(complexKey, Integer.class),
"getting complex type as integer should fail"
);
assertEquals(
complexVal,
assertDoesNotThrow(() -> res.get(complexKey + "Json", ComplexType.class), "getting complex type from JSON string failed"),
"unexpected value for complex type from JSON string"
complexVal,
assertDoesNotThrow(() -> res.get(complexKey + "Json", ComplexType.class), "getting complex type from JSON string failed"),
"unexpected value for complex type from JSON string"
);
}
@@ -199,8 +196,8 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
private Map<String, Object> toMap() {
return Map.of(
"field1", field1,
"field2", field2
"field1", field1,
"field2", field2
);
}

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -46,36 +45,36 @@ class SealResponseTest extends AbstractModelTest<SealResponse> {
private static final String STORAGE_TYPE = "file";
private static final String RES_SEALED = "{\n" +
" \"type\": \"" + TYPE + "\",\n" +
" \"sealed\": true,\n" +
" \"initialized\": true,\n" +
" \"t\": " + THRESHOLD + ",\n" +
" \"n\": " + SHARES + ",\n" +
" \"progress\": " + PROGRESS_SEALED + ",\n" +
" \"nonce\": \"\",\n" +
" \"version\": \"" + VERSION + "\",\n" +
" \"build_date\": \"" + BUILD_DATE + "\",\n" +
" \"migration\": \"" + MIGRATION + "\",\n" +
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
"}";
" \"type\": \"" + TYPE + "\",\n" +
" \"sealed\": true,\n" +
" \"initialized\": true,\n" +
" \"t\": " + THRESHOLD + ",\n" +
" \"n\": " + SHARES + ",\n" +
" \"progress\": " + PROGRESS_SEALED + ",\n" +
" \"nonce\": \"\",\n" +
" \"version\": \"" + VERSION + "\",\n" +
" \"build_date\": \"" + BUILD_DATE + "\",\n" +
" \"migration\": \"" + MIGRATION + "\",\n" +
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
"}";
private static final String RES_UNSEALED = "{\n" +
" \"type\": \"" + TYPE + "\",\n" +
" \"sealed\": false,\n" +
" \"initialized\": true,\n" +
" \"t\": " + THRESHOLD + ",\n" +
" \"n\": " + SHARES + ",\n" +
" \"progress\": " + PROGRESS_UNSEALED + ",\n" +
" \"version\": \"" + VERSION + "\",\n" +
" \"build_date\": \"" + BUILD_DATE + "\",\n" +
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
" \"nonce\": \"" + NONCE + "\",\n" +
" \"migration\": \"" + MIGRATION + "\",\n" +
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
"}";
" \"type\": \"" + TYPE + "\",\n" +
" \"sealed\": false,\n" +
" \"initialized\": true,\n" +
" \"t\": " + THRESHOLD + ",\n" +
" \"n\": " + SHARES + ",\n" +
" \"progress\": " + PROGRESS_UNSEALED + ",\n" +
" \"version\": \"" + VERSION + "\",\n" +
" \"build_date\": \"" + BUILD_DATE + "\",\n" +
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
" \"nonce\": \"" + NONCE + "\",\n" +
" \"migration\": \"" + MIGRATION + "\",\n" +
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
"}";
SealResponseTest() {
super(SealResponse.class);
@@ -83,12 +82,10 @@ class SealResponseTest extends AbstractModelTest<SealResponse> {
@Override
protected SealResponse createFull() {
try {
return objectMapper.readValue(RES_UNSEALED, SealResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(RES_UNSEALED, SealResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -98,8 +95,8 @@ class SealResponseTest extends AbstractModelTest<SealResponse> {
void jsonRoundtripSealed() {
// First test sealed Vault's response.
SealResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(RES_SEALED, SealResponse.class),
"SealResponse deserialization failed"
() -> objectMapper.readValue(RES_SEALED, SealResponse.class),
"SealResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertEquals(TYPE, res.getType(), "Incorrect seal type");
@@ -121,8 +118,8 @@ class SealResponseTest extends AbstractModelTest<SealResponse> {
// Not test unsealed Vault's response.
res = assertDoesNotThrow(
() -> objectMapper.readValue(RES_UNSEALED, SealResponse.class),
"SealResponse deserialization failed"
() -> objectMapper.readValue(RES_UNSEALED, SealResponse.class),
"SealResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertEquals(TYPE, res.getType(), "Incorrect seal type");

View File

@@ -16,13 +16,13 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* JUnit Test for {@link SecretListResponse} model.
@@ -34,17 +34,17 @@ class SecretListResponseTest extends AbstractModelTest<SecretListResponse> {
private static final String KEY1 = "key1";
private static final String KEY2 = "key-2";
private static final String JSON = "{\n" +
" \"auth\": null,\n" +
" \"data\": {\n" +
" \"keys\": [" +
" \"" + KEY1 + "\",\n" +
" \"" + KEY2 + "\"\n" +
" ]\n" +
" },\n" +
" \"lease_duration\": 2764800,\n" +
" \"lease_id\": \"\",\n" +
" \"renewable\": false\n" +
"}";
" \"auth\": null,\n" +
" \"data\": {\n" +
" \"keys\": [" +
" \"" + KEY1 + "\",\n" +
" \"" + KEY2 + "\"\n" +
" ]\n" +
" },\n" +
" \"lease_duration\": 2764800,\n" +
" \"lease_id\": \"\",\n" +
" \"renewable\": false\n" +
"}";
SecretListResponseTest() {
super(SecretListResponse.class);
@@ -52,12 +52,10 @@ class SecretListResponseTest extends AbstractModelTest<SecretListResponse> {
@Override
protected SecretListResponse createFull() {
try {
return objectMapper.readValue(JSON, SecretListResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(JSON, SecretListResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -66,8 +64,8 @@ class SecretListResponseTest extends AbstractModelTest<SecretListResponse> {
@Test
void getKeysTest() {
SecretListResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(JSON, SecretListResponse.class),
"SecretListResponse deserialization failed"
() -> objectMapper.readValue(JSON, SecretListResponse.class),
"SecretListResponse deserialization failed"
);
assertEquals(List.of(KEY1, KEY2), res.getKeys(), "Unexpected secret keys");

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -34,13 +33,13 @@ class SecretVersionResponseTest extends AbstractModelTest<SecretVersionResponse>
private static final Integer VERSION = 42;
private static final String META_JSON = "{\n" +
" \"data\": {\n" +
" \"created_time\": \"" + CREATION_TIME + "\",\n" +
" \"deletion_time\": \"" + DELETION_TIME + "\",\n" +
" \"destroyed\": false,\n" +
" \"version\": " + VERSION + "\n" +
" }\n" +
"}";
" \"data\": {\n" +
" \"created_time\": \"" + CREATION_TIME + "\",\n" +
" \"deletion_time\": \"" + DELETION_TIME + "\",\n" +
" \"destroyed\": false,\n" +
" \"version\": " + VERSION + "\n" +
" }\n" +
"}";
SecretVersionResponseTest() {
super(SecretVersionResponse.class);
@@ -48,12 +47,10 @@ class SecretVersionResponseTest extends AbstractModelTest<SecretVersionResponse>
@Override
protected SecretVersionResponse createFull() {
try {
return objectMapper.readValue(META_JSON, SecretVersionResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(META_JSON, SecretVersionResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -62,8 +59,8 @@ class SecretVersionResponseTest extends AbstractModelTest<SecretVersionResponse>
@Test
void jsonRoundtrip() {
SecretVersionResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(META_JSON, SecretVersionResponse.class),
"SecretVersionResponse deserialization failed"
() -> objectMapper.readValue(META_JSON, SecretVersionResponse.class),
"SecretVersionResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertNotNull(res.getMetadata(), "Parsed metadata is NULL");

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import de.stklcode.jvault.connector.model.response.embedded.TokenData;
import org.junit.jupiter.api.Test;
@@ -35,8 +34,8 @@ import static org.junit.jupiter.api.Assertions.*;
*/
class TokenResponseTest extends AbstractModelTest<TokenResponse> {
private static final Integer TOKEN_CREATION_TIME = 1457533232;
private static final Integer TOKEN_TTL = 2764800;
private static final Integer TOKEN_EXPLICIT_MAX_TTL = 0;
private static final Long TOKEN_TTL = 2764800L;
private static final Long TOKEN_EXPLICIT_MAX_TTL = 0L;
private static final String TOKEN_DISPLAY_NAME = "token";
private static final String TOKEN_META_KEY = "foo";
private static final String TOKEN_META_VALUE = "bar";
@@ -47,7 +46,7 @@ class TokenResponseTest extends AbstractModelTest<TokenResponse> {
private static final String TOKEN_POLICY_1 = "default";
private static final String TOKEN_POLICY_2 = "web";
private static final Boolean RES_RENEWABLE = false;
private static final Integer RES_TTL = 2591976;
private static final Long RES_TTL = 2591976L;
private static final Integer RES_LEASE_DURATION = 0;
private static final String TOKEN_ACCESSOR = "VKvzT2fKHFsZFUus9LyoXCvu";
private static final String TOKEN_ENTITY_ID = "7d2e3179-f69b-450c-7179-ac8ee8bd8ca9";
@@ -58,37 +57,37 @@ class TokenResponseTest extends AbstractModelTest<TokenResponse> {
private static final String MOUNT_TYPE = "token";
private static final String RES_JSON = "{\n" +
" \"lease_id\": \"\",\n" +
" \"renewable\": " + RES_RENEWABLE + ",\n" +
" \"lease_duration\": " + RES_LEASE_DURATION + ",\n" +
" \"data\": {\n" +
" \"accessor\": \"" + TOKEN_ACCESSOR + "\",\n" +
" \"creation_time\": " + TOKEN_CREATION_TIME + ",\n" +
" \"creation_ttl\": " + TOKEN_TTL + ",\n" +
" \"display_name\": \"" + TOKEN_DISPLAY_NAME + "\",\n" +
" \"entity_id\": \"" + TOKEN_ENTITY_ID + "\",\n" +
" \"expire_time\": \"" + TOKEN_EXPIRE_TIME + "\",\n" +
" \"explicit_max_ttl\": \"" + TOKEN_EXPLICIT_MAX_TTL + "\",\n" +
" \"id\": \"" + TOKEN_ID + "\",\n" +
" \"issue_time\": \"" + TOKEN_ISSUE_TIME + "\",\n" +
" \"meta\": {\n" +
" \"" + TOKEN_META_KEY + "\": \"" + TOKEN_META_VALUE + "\"\n" +
" },\n" +
" \"num_uses\": " + TOKEN_NUM_USES + ",\n" +
" \"orphan\": " + TOKEN_ORPHAN + ",\n" +
" \"path\": \"" + TOKEN_PATH + "\",\n" +
" \"policies\": [\n" +
" \"" + TOKEN_POLICY_1 + "\", \n" +
" \"" + TOKEN_POLICY_2 + "\"\n" +
" ],\n" +
" \"renewable\": " + TOKEN_RENEWABLE + ",\n" +
" \"ttl\": " + RES_TTL + ",\n" +
" \"type\": \"" + TOKEN_TYPE + "\"\n" +
" },\n" +
" \"warnings\": null,\n" +
" \"auth\": null,\n" +
" \"mount_type\": \"" + MOUNT_TYPE + "\"\n" +
"}";
" \"lease_id\": \"\",\n" +
" \"renewable\": " + RES_RENEWABLE + ",\n" +
" \"lease_duration\": " + RES_LEASE_DURATION + ",\n" +
" \"data\": {\n" +
" \"accessor\": \"" + TOKEN_ACCESSOR + "\",\n" +
" \"creation_time\": " + TOKEN_CREATION_TIME + ",\n" +
" \"creation_ttl\": " + TOKEN_TTL + ",\n" +
" \"display_name\": \"" + TOKEN_DISPLAY_NAME + "\",\n" +
" \"entity_id\": \"" + TOKEN_ENTITY_ID + "\",\n" +
" \"expire_time\": \"" + TOKEN_EXPIRE_TIME + "\",\n" +
" \"explicit_max_ttl\": \"" + TOKEN_EXPLICIT_MAX_TTL + "\",\n" +
" \"id\": \"" + TOKEN_ID + "\",\n" +
" \"issue_time\": \"" + TOKEN_ISSUE_TIME + "\",\n" +
" \"meta\": {\n" +
" \"" + TOKEN_META_KEY + "\": \"" + TOKEN_META_VALUE + "\"\n" +
" },\n" +
" \"num_uses\": " + TOKEN_NUM_USES + ",\n" +
" \"orphan\": " + TOKEN_ORPHAN + ",\n" +
" \"path\": \"" + TOKEN_PATH + "\",\n" +
" \"policies\": [\n" +
" \"" + TOKEN_POLICY_1 + "\", \n" +
" \"" + TOKEN_POLICY_2 + "\"\n" +
" ],\n" +
" \"renewable\": " + TOKEN_RENEWABLE + ",\n" +
" \"ttl\": " + RES_TTL + ",\n" +
" \"type\": \"" + TOKEN_TYPE + "\"\n" +
" },\n" +
" \"warnings\": null,\n" +
" \"auth\": null,\n" +
" \"mount_type\": \"" + MOUNT_TYPE + "\"\n" +
"}";
TokenResponseTest() {
super(TokenResponse.class);
@@ -96,12 +95,10 @@ class TokenResponseTest extends AbstractModelTest<TokenResponse> {
@Override
protected TokenResponse createFull() {
try {
return objectMapper.readValue(RES_JSON, TokenResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, TokenResponse.class),
"Creation of full model instance failed"
);
}
/**
@@ -120,8 +117,8 @@ class TokenResponseTest extends AbstractModelTest<TokenResponse> {
@Test
void jsonRoundtrip() {
TokenResponse res = assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, TokenResponse.class),
"TokenResponse deserialization failed"
() -> objectMapper.readValue(RES_JSON, TokenResponse.class),
"TokenResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertEquals(RES_LEASE_DURATION, res.getLeaseDuration(), "Incorrect lease duration");

View File

@@ -16,7 +16,6 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -39,19 +38,17 @@ class TransitResponseTest extends AbstractModelTest<TransitResponse> {
@Override
protected TransitResponse createFull() {
try {
return objectMapper.readValue(
return assertDoesNotThrow(
() -> objectMapper.readValue(
json(
"\"ciphertext\": \"" + CIPHERTEXT + "\", " +
"\"plaintext\": \"" + PLAINTEXT + "\", " +
"\"sum\": \"" + SUM + "\""
),
TransitResponse.class
);
} catch (JsonProcessingException e) {
fail("Creation of full model failed", e);
return null;
}
),
"Creation of full model failed"
);
}
@Test

View File

@@ -1,6 +1,5 @@
package de.stklcode.jvault.connector.model.response.embedded;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
@@ -14,8 +13,8 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer
*/
class MountConfigTest extends AbstractModelTest<MountConfig> {
private static final Integer DEFAULT_LEASE_TTL = 1800;
private static final Integer MAX_LEASE_TTL = 3600;
private static final Long DEFAULT_LEASE_TTL = 1800L;
private static final Long MAX_LEASE_TTL = 3600L;
private static final Boolean FORCE_NO_CACHE = false;
private static final String TOKEN_TYPE = "default-service";
private static final String AUDIT_NON_HMAC_REQ_KEYS_1 = "req1";
@@ -62,12 +61,10 @@ class MountConfigTest extends AbstractModelTest<MountConfig> {
@Override
protected MountConfig createFull() {
try {
return objectMapper.readValue(RES_JSON, MountConfig.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
return assertDoesNotThrow(
() -> objectMapper.readValue(RES_JSON, MountConfig.class),
"Creation of full model instance failed"
);
}
/**

View File

@@ -93,14 +93,14 @@ public class VaultConfiguration {
@Override
public String toString() {
return "storage \"file\" {\n" +
" path = \"" + dataLocation + "\"\n" +
"}\n" +
"listener \"tcp\" {\n" +
" address = \"" + host + ":" + port + "\"\n" +
((disableTLS) ? " tls_disable = 1\n" : "") +
((certFile != null) ? " tls_cert_file = \"" + certFile + "\"\n" : "") +
((keyFile != null) ? " tls_key_file = \"" + keyFile + "\"\n" : "") +
"}\n" +
((disableMlock) ? "disable_mlock = true" : "");
" path = \"" + dataLocation + "\"\n" +
"}\n" +
"listener \"tcp\" {\n" +
" address = \"" + host + ":" + port + "\"\n" +
((disableTLS) ? " tls_disable = 1\n" : "") +
((certFile != null) ? " tls_cert_file = \"" + certFile + "\"\n" : "") +
((keyFile != null) ? " tls_key_file = \"" + keyFile + "\"\n" : "") +
"}\n" +
((disableMlock) ? "disable_mlock = true" : "");
}
}