Skip to content

Commit 34f038c

Browse files
authored
vjd-10 Retry logic refactoring (#12)
1 parent e797cad commit 34f038c

File tree

9 files changed

+1830
-2251
lines changed

9 files changed

+1830
-2251
lines changed

src/main/java/io/github/jopenlibs/vault/api/Auth.java

Lines changed: 755 additions & 906 deletions
Large diffs are not rendered by default.

src/main/java/io/github/jopenlibs/vault/api/Debug.java

Lines changed: 78 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,28 @@
44
import io.github.jopenlibs.vault.VaultException;
55
import io.github.jopenlibs.vault.response.HealthResponse;
66
import io.github.jopenlibs.vault.rest.Rest;
7-
import io.github.jopenlibs.vault.rest.RestException;
87
import io.github.jopenlibs.vault.rest.RestResponse;
98
import java.util.HashSet;
109
import java.util.Set;
1110

1211

1312
/**
14-
* <p>The implementing class for operations on REST endpoints, under the "Debug" section of the Vault HTTP API
13+
* <p>The implementing class for operations on REST endpoints, under the "Debug" section of the
14+
* Vault HTTP API
1515
* docs (https://www.vaultproject.io/docs/http/index.html).</p>
1616
*
1717
* <p>This class is not intended to be constructed directly. Rather, it is meant to used by way of
18-
* <code>Vault</code> in a DSL-style builder pattern. See the Javadoc comments of each <code>public</code>
18+
* <code>Vault</code> in a DSL-style builder pattern. See the Javadoc comments of each
19+
* <code>public</code>
1920
* method for usage examples.</p>
2021
*/
21-
public class Debug {
22-
23-
private final VaultConfig config;
22+
public class Debug extends OperationsBase {
2423

2524
private String nameSpace;
2625

2726
public Debug(final VaultConfig config) {
28-
this.config = config;
27+
super(config);
28+
2929
if (this.config.getNameSpace() != null && !this.config.getNameSpace().isEmpty()) {
3030
this.nameSpace = this.config.getNameSpace();
3131
}
@@ -42,8 +42,10 @@ public Debug withNameSpace(final String nameSpace) {
4242
* health check and provides a simple way to monitor the health of a Vault instance.</p>
4343
*
4444
* @return The response information returned from Vault
45-
* @throws VaultException If any errors occurs with the REST request (e.g. non-200 status code, invalid JSON payload, etc), and the maximum number of retries is exceeded.
46-
* @see <a href="https://www.vaultproject.io/docs/http/sys-health.html">https://www.vaultproject.io/docs/http/sys-health.html</a>
45+
* @throws VaultException If any errors occurs with the REST request (e.g. non-200 status code,
46+
* invalid JSON payload, etc), and the maximum number of retries is exceeded.
47+
* @see <a
48+
* href="https://www.vaultproject.io/docs/http/sys-health.html">https://www.vaultproject.io/docs/http/sys-health.html</a>
4749
*
4850
* <blockquote>
4951
* <pre>{@code
@@ -61,19 +63,27 @@ public HealthResponse health() throws VaultException {
6163
}
6264

6365
/**
64-
* <p>An overloaded version of {@link Debug#health()} that allows for passing one or more optional parameters.</p>
66+
* <p>An overloaded version of {@link Debug#health()} that allows for passing one or more
67+
* optional parameters.</p>
6568
*
66-
* <p>WARNING: In testing, we've found that changing the default HTTP status codes can result in the operation
67-
* succeeding, but returning an empty JSON payload in the response. For example, this seems to happen when you
68-
* set <code>activeCode</code> to 204, but not for 212 (the regular default is 200). When this happens, the
69-
* <code>HealthResponse</code> return object will have <code>null</code> values in most of its fields, and you
70-
* will need to check <code>HealthReponse.getRestResponse().getStatus()</code> to determine the result of
71-
* the operation.</p>
69+
* <p>WARNING: In testing, we've found that changing the default HTTP status codes can result
70+
* in the operation
71+
* succeeding, but returning an empty JSON payload in the response. For example, this seems to
72+
* happen when you set <code>activeCode</code> to 204, but not for 212 (the regular default is
73+
* 200). When this happens, the
74+
* <code>HealthResponse</code> return object will have <code>null</code> values in most of its
75+
* fields, and you
76+
* will need to check <code>HealthReponse.getRestResponse().getStatus()</code> to determine the
77+
* result of the operation.</p>
7278
*
73-
* @param standbyOk (optional) Indicates that being a standby should still return the active status code instead of the standby code
74-
* @param activeCode (optional) Indicates the status code that should be returned for an active node instead of the default of 200
75-
* @param standbyCode (optional) Indicates the status code that should be returned for a standby node instead of the default of 429
76-
* @param sealedCode (optional) Indicates the status code that should be returned for a sealed node instead of the default of 500
79+
* @param standbyOk (optional) Indicates that being a standby should still return the active
80+
* status code instead of the standby code
81+
* @param activeCode (optional) Indicates the status code that should be returned for an active
82+
* node instead of the default of 200
83+
* @param standbyCode (optional) Indicates the status code that should be returned for a standby
84+
* node instead of the default of 429
85+
* @param sealedCode (optional) Indicates the status code that should be returned for a sealed
86+
* node instead of the default of 500
7787
* @return The response information returned from Vault
7888
* @throws VaultException If an error occurs or unexpected response received from Vault
7989
*/
@@ -84,56 +94,55 @@ public HealthResponse health(
8494
final Integer sealedCode
8595
) throws VaultException {
8696
final String path = "sys/health";
87-
int retryCount = 0;
88-
while (true) {
89-
try {
90-
// Build an HTTP request for Vault
91-
final Rest rest = new Rest()//NOPMD
92-
.url(config.getAddress() + "/v1/" + path)
93-
.header("X-Vault-Token", config.getToken())
94-
.header("X-Vault-Namespace", this.nameSpace)
95-
.connectTimeoutSeconds(config.getOpenTimeout())
96-
.readTimeoutSeconds(config.getReadTimeout())
97-
.sslVerification(config.getSslConfig().isVerify())
98-
.sslContext(config.getSslConfig().getSslContext());
99-
// Add params if present
100-
if (standbyOk != null) rest.parameter("standbyok", standbyOk.toString());
101-
if (activeCode != null) rest.parameter("activecode", activeCode.toString());
102-
if (standbyCode != null) rest.parameter("standbycode", standbyCode.toString());
103-
if (sealedCode != null) rest.parameter("sealedcode", sealedCode.toString());
104-
// Execute request
105-
final RestResponse restResponse = rest.get();
10697

107-
// Validate response
108-
final Set<Integer> validCodes = new HashSet<>();//NOPMD
109-
validCodes.add(200);
110-
validCodes.add(429);
111-
validCodes.add(500);
112-
if (activeCode != null) validCodes.add(activeCode);
113-
if (standbyCode != null) validCodes.add(standbyCode);
114-
if (sealedCode != null) validCodes.add(sealedCode);
115-
if (!validCodes.contains(restResponse.getStatus())) {
116-
throw new VaultException("Vault responded with HTTP status code: " + restResponse.getStatus(), restResponse.getStatus());
117-
}
118-
return new HealthResponse(restResponse, retryCount);
119-
} catch (RuntimeException | VaultException | RestException e) {
120-
// If there are retries to perform, then pause for the configured interval and then execute the loop again...
121-
if (retryCount < config.getMaxRetries()) {
122-
retryCount++;
123-
try {
124-
final int retryIntervalMilliseconds = config.getRetryIntervalMilliseconds();
125-
Thread.sleep(retryIntervalMilliseconds);
126-
} catch (InterruptedException e1) {
127-
e1.printStackTrace();
128-
}
129-
} else if (e instanceof VaultException) {
130-
// ... otherwise, give up.
131-
throw (VaultException) e;
132-
} else {
133-
throw new VaultException(e);
134-
}
98+
return retry(attempt -> {
99+
// Build an HTTP request for Vault
100+
final Rest rest = new Rest()//NOPMD
101+
.url(config.getAddress() + "/v1/" + path)
102+
.header("X-Vault-Token", config.getToken())
103+
.header("X-Vault-Namespace", this.nameSpace)
104+
.connectTimeoutSeconds(config.getOpenTimeout())
105+
.readTimeoutSeconds(config.getReadTimeout())
106+
.sslVerification(config.getSslConfig().isVerify())
107+
.sslContext(config.getSslConfig().getSslContext());
108+
// Add params if present
109+
if (standbyOk != null) {
110+
rest.parameter("standbyok", standbyOk.toString());
135111
}
136-
}
137-
}
112+
if (activeCode != null) {
113+
rest.parameter("activecode", activeCode.toString());
114+
}
115+
if (standbyCode != null) {
116+
rest.parameter("standbycode", standbyCode.toString());
117+
}
118+
if (sealedCode != null) {
119+
rest.parameter("sealedcode", sealedCode.toString());
120+
}
121+
// Execute request
122+
final RestResponse restResponse = rest.get();
138123

124+
// Validate response
125+
final Set<Integer> validCodes = new HashSet<>();//NOPMD
126+
validCodes.add(200);
127+
validCodes.add(429);
128+
validCodes.add(500);
129+
if (activeCode != null) {
130+
validCodes.add(activeCode);
131+
}
132+
if (standbyCode != null) {
133+
validCodes.add(standbyCode);
134+
}
135+
if (sealedCode != null) {
136+
validCodes.add(sealedCode);
137+
}
138+
139+
if (!validCodes.contains(restResponse.getStatus())) {
140+
throw new VaultException(
141+
"Vault responded with HTTP status code: " + restResponse.getStatus(),
142+
restResponse.getStatus());
143+
}
144+
145+
return new HealthResponse(restResponse, attempt);
146+
});
147+
}
139148
}

0 commit comments

Comments
 (0)