From 2b0f458da3dd996a69a8483a7c610cf70552e408 Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Sun, 28 Feb 2021 10:52:36 +0100 Subject: [PATCH] use pre-sized maps for fixed-size payloads --- .drone.yml | 10 +- .travis.yml | 4 +- CHANGELOG.md | 8 ++ README.md | 2 +- pom.xml | 2 +- .../jvault/connector/HTTPVaultConnector.java | 95 +++++++++++-------- .../jvault/connector/VaultConnector.java | 13 +-- .../model/response/AppRoleResponse.java | 2 +- .../model/response/AppRoleSecretResponse.java | 2 +- .../model/response/SecretResponse.java | 4 +- .../connector/HTTPVaultConnectorTest.java | 2 +- 11 files changed, 82 insertions(+), 62 deletions(-) diff --git a/.drone.yml b/.drone.yml index 972add4..145233f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -25,12 +25,12 @@ steps: - name: unit-integration-tests image: maven:3-jdk-11 environment: - VAULT_VERSION: 1.6.1 + VAULT_VERSION: 1.6.2 commands: - - curl -s -o vault_1.6.1_linux_amd64.zip https://releases.hashicorp.com/vault/1.6.1/vault_1.6.1_linux_amd64.zip - - curl -s https://releases.hashicorp.com/vault/1.6.1/vault_1.6.1_SHA256SUMS | grep linux_amd64 | sha256sum -c - - unzip vault_1.6.1_linux_amd64.zip - - rm vault_1.6.1_linux_amd64.zip + - curl -s -o vault_1.6.2_linux_amd64.zip https://releases.hashicorp.com/vault/1.6.2/vault_1.6.2_linux_amd64.zip + - curl -s https://releases.hashicorp.com/vault/1.6.2/vault_1.6.2_SHA256SUMS | grep linux_amd64 | sha256sum -c + - unzip vault_1.6.2_linux_amd64.zip + - rm vault_1.6.2_linux_amd64.zip - mv vault /bin/ - mvn -B resources:testResources compiler:testCompile surefire:test when: diff --git a/.travis.yml b/.travis.yml index c5c8ec3..3e2bc6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ addons: secure: "sM9OfX5jW764pn9cb2LSXArnXucKMws+eGeg5NnZxHRcGYt4hpBKLSregBSsBNzUoWVj0zNzPCpnh+UQvgxQzUerOqwEdjTBpy3SNPaxSn7UpoSg+Wz3aUmL9ugmx01b51/wMG4UCHEwTZt2tpgTPVtw8K6uSO78e0dSICCBHDnRcdQwOjMEQHIJJ/qHVRwuy/MzLCAP3W1JPZlsphZg9QsFyhB4hW97dE90joZezfocQIv2xI/r6k+BLz0pY6MxYCul0RiDumaiaej0CPvEJI/uSu//BAQjUdHw+mQgnKUYIbrn2ONOviwNfwdr94JyoZEN2B6zASUmNLjPf4AbIojDeyS+CrpQpm17EVm/Qk/Ds+Xra4PPPIcsZhiWzV0KoDUz9xLfXuRJ526VT5tDPiaeI7oETf0+8l+JIS1b399FyqHi7smzjpvC6GuKflQrbuHK4MuKzDh7WTHiqokGG4SS0wOQIaaHB3dfdwwQzPh6IM24e8CETxh3DjMeqUTU4DWmv5po55jZ934TtxVQvVN78bTG9O0zS9u+JmRY04OZ+OaXuFam6MfMUFQi0EPZzdGul/oWSibGUu3bNfVEBp60CnJwYNM/dKG6U7pJthLHvSwiQFOdKzHZ+l1jZJ4gPaXaIGqpwqVGr28ntqA/El1rytPixr2driE6bYMt5jw=" env: - - PATH=$PATH:. VAULT_VERSION=1.6.1 ANALYSIS=false + - PATH=$PATH:. VAULT_VERSION=1.6.2 ANALYSIS=false cache: directories: @@ -18,7 +18,7 @@ jobs: include: - jdk: openjdk8 - jdk: openjdk11 - env: PATH=$PATH:. VAULT_VERSION=1.6.1 ANALYSIS=true + env: PATH=$PATH:. VAULT_VERSION=1.6.2 ANALYSIS=true - jdk: openjdk15 before_script: diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e5d591..7590589 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## unreleased + +### Improvements +* Use pre-sized map objects for fixed-size payloads + +### Test +* Tested against Vault 1.6.2 + ## 0.9.2 (2021-01-24) ### Fixes diff --git a/README.md b/README.md index 6ecf951..32b012d 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject * SQL secret handling * KV v1 and v2 support * Connector Factory with builder pattern -* Tested against Vault 1.6.1 +* Tested against Vault 1.6.2 ## Maven Artifact diff --git a/pom.xml b/pom.xml index cbb8d9e..5e5f197 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ de.stklcode.jvault jvault-connector - 0.9.2 + 0.9.3-SNAPSHOPT jar diff --git a/src/main/java/de/stklcode/jvault/connector/HTTPVaultConnector.java b/src/main/java/de/stklcode/jvault/connector/HTTPVaultConnector.java index ef3f99e..5e6dfb3 100644 --- a/src/main/java/de/stklcode/jvault/connector/HTTPVaultConnector.java +++ b/src/main/java/de/stklcode/jvault/connector/HTTPVaultConnector.java @@ -25,11 +25,15 @@ import de.stklcode.jvault.connector.model.response.*; import de.stklcode.jvault.connector.model.response.embedded.AuthMethod; import java.security.cert.X509Certificate; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; + /** * Vault Connector implementation using Vault's HTTP API. * @@ -222,17 +226,17 @@ public class HTTPVaultConnector implements VaultConnector { @Override public final SealResponse sealStatus() throws VaultConnectorException { - return request.get(PATH_SEAL_STATUS, new HashMap<>(), token, SealResponse.class); + return request.get(PATH_SEAL_STATUS, emptyMap(), token, SealResponse.class); } @Override public final void seal() throws VaultConnectorException { - request.put(PATH_SEAL, new HashMap<>(), token); + request.put(PATH_SEAL, emptyMap(), token); } @Override public final SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException { - Map param = new HashMap<>(); + Map param = new HashMap<>(2, 1); param.put("key", key); if (reset != null) { param.put("reset", reset.toString()); @@ -244,7 +248,7 @@ public class HTTPVaultConnector implements VaultConnector { @Override public HealthResponse getHealth() throws VaultConnectorException { /* Force status code to be 200, so we don't need to modify the request sequence. */ - Map param = new HashMap<>(); + Map param = new HashMap<>(3, 1); param.put("standbycode", "200"); // Default: 429. param.put("sealedcode", "200"); // Default: 503. param.put("uninitcode", "200"); // Default: 501. @@ -260,7 +264,7 @@ public class HTTPVaultConnector implements VaultConnector { @Override public final List getAuthBackends() throws VaultConnectorException { /* Issue request and parse response */ - AuthMethodsResponse amr = request.get(PATH_AUTH, new HashMap<>(), token, AuthMethodsResponse.class); + AuthMethodsResponse amr = request.get(PATH_AUTH, emptyMap(), token, AuthMethodsResponse.class); return amr.getSupportedMethods().values().stream().map(AuthMethod::getType).collect(Collectors.toList()); } @@ -270,7 +274,7 @@ public class HTTPVaultConnector implements VaultConnector { /* set token */ this.token = token; this.tokenTTL = 0; - TokenResponse res = request.post(PATH_TOKEN + PATH_LOOKUP, new HashMap<>(), token, TokenResponse.class); + TokenResponse res = request.post(PATH_TOKEN + PATH_LOOKUP, emptyMap(), token, TokenResponse.class); authorized = true; return res; @@ -279,15 +283,14 @@ public class HTTPVaultConnector implements VaultConnector { @Override public final AuthResponse authUserPass(final String username, final String password) throws VaultConnectorException { - final Map payload = new HashMap<>(); - payload.put("password", password); + final Map payload = singletonMap("password", password); return queryAuth(PATH_AUTH_USERPASS + username, payload); } @Override @Deprecated public final AuthResponse authAppId(final String appID, final String userID) throws VaultConnectorException { - final Map payload = new HashMap<>(); + final Map payload = new HashMap<>(2, 1); payload.put("app_id", appID); payload.put("user_id", userID); return queryAuth(PATH_AUTH_APPID + "login", payload); @@ -295,7 +298,7 @@ public class HTTPVaultConnector implements VaultConnector { @Override public final AuthResponse authAppRole(final String roleID, final String secretID) throws VaultConnectorException { - final Map payload = new HashMap<>(); + final Map payload = new HashMap<>(2, 1); payload.put("role_id", roleID); if (secretID != null) { payload.put("secret_id", secretID); @@ -328,7 +331,7 @@ public class HTTPVaultConnector implements VaultConnector { public final boolean registerAppId(final String appID, final String policy, final String displayName) throws VaultConnectorException { requireAuth(); - Map payload = new HashMap<>(); + Map payload = new HashMap<>(2, 1); payload.put("value", policy); payload.put("display_name", displayName); @@ -342,11 +345,13 @@ public class HTTPVaultConnector implements VaultConnector { @Deprecated public final boolean registerUserId(final String appID, final String userID) throws VaultConnectorException { requireAuth(); - Map payload = new HashMap<>(); - payload.put("value", appID); /* Issue request and expect code 204 with empty response */ - request.postWithoutResponse(PATH_AUTH_APPID + "map/user-id/" + userID, payload, token); + request.postWithoutResponse( + PATH_AUTH_APPID + "map/user-id/" + userID, + singletonMap("value", appID), + token + ); return true; } @@ -366,7 +371,12 @@ public class HTTPVaultConnector implements VaultConnector { public final AppRoleResponse lookupAppRole(final String roleName) throws VaultConnectorException { requireAuth(); /* Request HTTP response and parse Secret */ - return request.get(String.format(PATH_AUTH_APPROLE_ROLE, roleName, ""), new HashMap<>(), token, AppRoleResponse.class); + return request.get( + String.format(PATH_AUTH_APPROLE_ROLE, roleName, ""), + emptyMap(), + token, + AppRoleResponse.class + ); } @Override @@ -385,7 +395,7 @@ public class HTTPVaultConnector implements VaultConnector { /* Issue request, parse response and extract Role ID */ return request.get( String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"), - new HashMap<>(), + emptyMap(), token, RawDataResponse.class ).getData().get("role_id").toString(); @@ -394,12 +404,13 @@ public class HTTPVaultConnector implements VaultConnector { @Override public final boolean setAppRoleID(final String roleName, final String roleID) throws VaultConnectorException { requireAuth(); - /* Request HTTP response and parse Secret */ - Map payload = new HashMap<>(); - payload.put("role_id", roleID); /* Issue request and expect code 204 with empty response */ - request.postWithoutResponse(String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"), payload, token); + request.postWithoutResponse( + String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"), + singletonMap("role_id", roleID), + token + ); return true; } @@ -457,7 +468,13 @@ public class HTTPVaultConnector implements VaultConnector { public final List listAppRoles() throws VaultConnectorException { requireAuth(); - SecretListResponse secrets = request.get(PATH_AUTH_APPROLE + "role?list=true", new HashMap<>(), token, SecretListResponse.class); + SecretListResponse secrets = request.get( + PATH_AUTH_APPROLE + "role?list=true", + emptyMap(), + token, + SecretListResponse.class + ); + return secrets.getKeys(); } @@ -467,7 +484,7 @@ public class HTTPVaultConnector implements VaultConnector { SecretListResponse secrets = request.get( String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/secret-id?list=true"), - new HashMap<>(), + emptyMap(), token, SecretListResponse.class ); @@ -479,14 +496,14 @@ public class HTTPVaultConnector implements VaultConnector { public final SecretResponse read(final String key) throws VaultConnectorException { requireAuth(); /* Issue request and parse secret response */ - return request.get(key, new HashMap<>(), token, SecretResponse.class); + return request.get(key, emptyMap(), token, SecretResponse.class); } @Override public final SecretResponse readSecretVersion(final String mount, final String key, final Integer version) throws VaultConnectorException { requireAuth(); /* Request HTTP response and parse secret metadata */ - Map args = new HashMap<>(); + Map args = new HashMap<>(1, 1); if (version != null) { args.put("version", version.toString()); } @@ -499,14 +516,14 @@ public class HTTPVaultConnector implements VaultConnector { requireAuth(); /* Request HTTP response and parse secret metadata */ - return request.get(mount + PATH_METADATA + key, new HashMap<>(), token, MetadataResponse.class); + return request.get(mount + PATH_METADATA + key, emptyMap(), token, MetadataResponse.class); } @Override public void updateSecretMetadata(final String mount, final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException { requireAuth(); - Map payload = new HashMap<>(); + Map payload = new HashMap<>(2, 1); if (maxVersions != null) { payload.put("max_versions", maxVersions); } @@ -524,12 +541,12 @@ public class HTTPVaultConnector implements VaultConnector { } // Add CAS value to options map if present. - Map options = new HashMap<>(); + Map options = new HashMap<>(1, 1); if (cas != null) { options.put("cas", cas); } - Map payload = new HashMap<>(); + Map payload = new HashMap<>(2, 1); payload.put("data", data); payload.put("options", options); @@ -541,7 +558,7 @@ public class HTTPVaultConnector implements VaultConnector { public final List list(final String path) throws VaultConnectorException { requireAuth(); - SecretListResponse secrets = request.get(path + "/?list=true", new HashMap<>(), token, SecretListResponse.class); + SecretListResponse secrets = request.get(path + "/?list=true", emptyMap(), token, SecretListResponse.class); return secrets.getKeys(); } @@ -559,7 +576,7 @@ public class HTTPVaultConnector implements VaultConnector { // If options are given, split payload in two parts. if (options != null) { - Map payloadMap = new HashMap<>(); + Map payloadMap = new HashMap<>(2, 1); payloadMap.put("data", data); payloadMap.put("options", options); payload = payloadMap; @@ -616,8 +633,7 @@ public class HTTPVaultConnector implements VaultConnector { requireAuth(); /* Request HTTP response and expect empty result */ - Map payload = new HashMap<>(); - payload.put("versions", versions); + Map payload = singletonMap("versions", versions); /* Issue request and expect code 204 with empty response */ request.postWithoutResponse(mount + pathPart + key, payload, token); @@ -628,14 +644,14 @@ public class HTTPVaultConnector implements VaultConnector { requireAuth(); /* Issue request and expect code 204 with empty response */ - request.putWithoutResponse(PATH_REVOKE + leaseID, new HashMap<>(), token); + request.putWithoutResponse(PATH_REVOKE + leaseID, emptyMap(), token); } @Override public final SecretResponse renew(final String leaseID, final Integer increment) throws VaultConnectorException { requireAuth(); - Map payload = new HashMap<>(); + Map payload = new HashMap<>(2, 1); payload.put("lease_id", leaseID); if (increment != null) { payload.put("increment", increment.toString()); @@ -694,9 +710,12 @@ public class HTTPVaultConnector implements VaultConnector { requireAuth(); /* Request HTTP response and parse Secret */ - Map param = new HashMap<>(); - param.put("token", token); - return request.get(PATH_TOKEN + PATH_LOOKUP, param, token, TokenResponse.class); + return request.get( + PATH_TOKEN + PATH_LOOKUP, + singletonMap("token", token), + token, + TokenResponse.class + ); } @Override @@ -720,7 +739,7 @@ public class HTTPVaultConnector implements VaultConnector { requireAuth(); // Request HTTP response and parse response. - return request.get(PATH_TOKEN + PATH_ROLES + "/" + name, new HashMap<>(), token, TokenRoleResponse.class); + return request.get(PATH_TOKEN + PATH_ROLES + "/" + name, emptyMap(), token, TokenRoleResponse.class); } @Override diff --git a/src/main/java/de/stklcode/jvault/connector/VaultConnector.java b/src/main/java/de/stklcode/jvault/connector/VaultConnector.java index d2f9c1b..4fc1a0f 100644 --- a/src/main/java/de/stklcode/jvault/connector/VaultConnector.java +++ b/src/main/java/de/stklcode/jvault/connector/VaultConnector.java @@ -22,10 +22,7 @@ import de.stklcode.jvault.connector.model.*; import de.stklcode.jvault.connector.model.response.*; import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Vault Connector interface. @@ -611,9 +608,7 @@ public interface VaultConnector extends AutoCloseable, Serializable { * @since 0.5.0 */ default void write(final String key, final String value) throws VaultConnectorException { - Map param = new HashMap<>(); - param.put("value", value); - write(key, param); + write(key, Collections.singletonMap("value", value)); } /** @@ -649,9 +644,7 @@ public interface VaultConnector extends AutoCloseable, Serializable { * @throws VaultConnectorException on error */ default void writeSecret(final String key, final String value) throws VaultConnectorException { - Map param = new HashMap<>(); - param.put("value", value); - writeSecret(key, param); + writeSecret(key, Collections.singletonMap("value", value)); } /** diff --git a/src/main/java/de/stklcode/jvault/connector/model/response/AppRoleResponse.java b/src/main/java/de/stklcode/jvault/connector/model/response/AppRoleResponse.java index 9d148e1..6c8582b 100644 --- a/src/main/java/de/stklcode/jvault/connector/model/response/AppRoleResponse.java +++ b/src/main/java/de/stklcode/jvault/connector/model/response/AppRoleResponse.java @@ -40,7 +40,7 @@ public final class AppRoleResponse extends VaultDataResponse { ObjectMapper mapper = new ObjectMapper(); try { /* null empty strings on list objects */ - Map filteredData = new HashMap<>(); + Map filteredData = new HashMap<>(data.size(), 1); data.forEach((k, v) -> { if (!(v instanceof String && ((String) v).isEmpty())) { filteredData.put(k, v); diff --git a/src/main/java/de/stklcode/jvault/connector/model/response/AppRoleSecretResponse.java b/src/main/java/de/stklcode/jvault/connector/model/response/AppRoleSecretResponse.java index 9b22d0d..6707e22 100644 --- a/src/main/java/de/stklcode/jvault/connector/model/response/AppRoleSecretResponse.java +++ b/src/main/java/de/stklcode/jvault/connector/model/response/AppRoleSecretResponse.java @@ -40,7 +40,7 @@ public final class AppRoleSecretResponse extends VaultDataResponse { ObjectMapper mapper = new ObjectMapper(); try { /* null empty strings on list objects */ - Map filteredData = new HashMap<>(); + Map filteredData = new HashMap<>(data.size(), 1); data.forEach((k, v) -> { if (!(v instanceof String && ((String) v).isEmpty())) { filteredData.put(k, v); diff --git a/src/main/java/de/stklcode/jvault/connector/model/response/SecretResponse.java b/src/main/java/de/stklcode/jvault/connector/model/response/SecretResponse.java index eb0e2e0..ae59860 100644 --- a/src/main/java/de/stklcode/jvault/connector/model/response/SecretResponse.java +++ b/src/main/java/de/stklcode/jvault/connector/model/response/SecretResponse.java @@ -22,7 +22,7 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata; import java.io.IOException; -import java.util.HashMap; +import java.util.Collections; import java.util.Map; /** @@ -66,7 +66,7 @@ public class SecretResponse extends VaultDataResponse { */ public final Map getData() { if (data == null) { - return new HashMap<>(); + return Collections.emptyMap(); } return data; } diff --git a/src/test/java/de/stklcode/jvault/connector/HTTPVaultConnectorTest.java b/src/test/java/de/stklcode/jvault/connector/HTTPVaultConnectorTest.java index 6c4d265..f70e3cd 100644 --- a/src/test/java/de/stklcode/jvault/connector/HTTPVaultConnectorTest.java +++ b/src/test/java/de/stklcode/jvault/connector/HTTPVaultConnectorTest.java @@ -53,7 +53,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; */ @Tag("online") class HTTPVaultConnectorTest { - private static String VAULT_VERSION = "1.6.1"; // the vault version this test is supposed to run against + private static String VAULT_VERSION = "1.6.2"; // the vault version this test is supposed to run against private static final String KEY1 = "E38bkCm0VhUvpdCKGQpcohhD9XmcHJ/2hreOSY019Lho"; private static final String KEY2 = "O5OHwDleY3IiPdgw61cgHlhsrEm6tVJkrxhF6QAnILd1"; private static final String KEY3 = "mw7Bm3nbt/UWa/juDjjL2EPQ04kiJ0saC5JEXwJvXYsB";