com.hashicorp.nomad.javasdk.ApiBase Maven / Gradle / Ivy
package com.hashicorp.nomad.javasdk;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import javax.annotation.Nullable;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
/**
* Common implementation functions for the API classes that are accessible from
* the {@link NomadApiClient}.
*/
abstract class ApiBase {
protected final NomadApiClient apiClient;
protected ApiBase(final NomadApiClient apiClient) {
this.apiClient = apiClient;
}
// URI Building
protected URIBuilder uri(final String path) {
return uri(apiClient.getAddress(), path);
}
protected URIBuilder uri(final HttpHost address, final String path) {
return new URIBuilder()
.setScheme(address.getSchemeName())
.setHost(address.getHostName())
.setPort(address.getPort())
.setPath(path);
}
// Request Building
protected RequestBuilder get(final String path) {
return get(uri(path));
}
protected RequestBuilder get(final URIBuilder uri) {
return RequestBuilder.get(build(uri));
}
protected RequestBuilder put(final String path, @Nullable final WriteOptions options) {
return put(uri(path), options);
}
protected RequestBuilder put(final URIBuilder uri, @Nullable final WriteOptions options) {
return prepareWrite(RequestBuilder.put(), uri, options);
}
protected RequestBuilder put(final String path, final Object requestEntity, @Nullable final WriteOptions options) {
return put(uri(path), requestEntity, options);
}
protected RequestBuilder put(
final URIBuilder uri,
final Object requestEntity,
@Nullable final WriteOptions options
) {
return prepareWrite(RequestBuilder.put(), uri, options)
.setEntity(new StringEntity(NomadJson.serialize(requestEntity), ContentType.APPLICATION_JSON));
}
protected RequestBuilder delete(final URIBuilder uri, @Nullable final WriteOptions options) {
return prepareWrite(RequestBuilder.delete(), uri, options);
}
// Execution
protected NomadResponse executePlain(
final RequestBuilder request,
@Nullable final ValueExtractor valueExtractor) throws IOException, NomadException {
return apiClient.execute(request, new NomadResponseAdapter<>(valueExtractor));
}
protected ServerResponse executeServerAction(
final RequestBuilder request,
@Nullable final ValueExtractor valueExtractor) throws IOException, NomadException {
return apiClient.execute(request, new ServerResponseAdapter<>(valueExtractor));
}
protected ServerQueryResponse executeServerQuery(
final String path,
@Nullable final QueryOptions options,
@Nullable final ValueExtractor valueExtractor
) throws IOException, NomadException {
return executeServerQuery(uri(path), options, valueExtractor);
}
protected ServerQueryResponse executeServerQuery(
final URIBuilder uriBuilder,
@Nullable final QueryOptions options,
@Nullable final ValueExtractor valueExtractor
) throws IOException, NomadException {
final URI uri = build(uriBuilder);
final WaitStrategy waitStrategy = options == null ? null : options.getWaitStrategy();
final Predicate> predicate = options == null ? null : options.getRepeatedPollPredicate();
ServerQueryResponse response = null;
while (true) {
response = executeServerQueryRaw(
options, getWait(waitStrategy, response), valueExtractor, RequestBuilder.get(uri));
if (predicate == null || predicate.apply(response))
return response;
final BigInteger targetIndex = BigInteger.ZERO.equals(response.getIndex())
? BigInteger.ONE
: response.getIndex();
if (options.getIndex() == null || targetIndex.compareTo(options.getIndex()) < 0)
options.setIndex(targetIndex);
}
}
protected ServerQueryResponse executeServerQueryPut(
final URIBuilder uriBuilder,
Object entity,
@Nullable final QueryOptions options,
@Nullable final ValueExtractor valueExtractor
) throws IOException, NomadException {
final WaitStrategy waitStrategy = options == null ? null : options.getWaitStrategy();
final Predicate> predicate = options == null ? null : options.getRepeatedPollPredicate();
ServerQueryResponse response = null;
while (true) {
response = executeServerQueryRaw(options, getWait(waitStrategy, response), valueExtractor,
put(uriBuilder, entity, null));
if (predicate == null || predicate.apply(response))
return response;
options.setIndex(response.getIndex());
}
}
protected > ServerQueryResponse executeServerQueryForPrefixFilteredList(
final String path,
@Nullable final String prefix,
@Nullable final QueryOptions options,
@Nullable final ValueExtractor valueExtractor
) throws IOException, NomadException {
final URIBuilder uri = uri(path);
if (prefix != null) {
uri.addParameter("prefix", prefix);
}
return executeServerQuery(uri, options, valueExtractor);
}
private URI build(URIBuilder uriBuilder) {
try {
return uriBuilder.build();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
private String getWait(
@Nullable final WaitStrategy waitStrategy,
@Nullable final ServerQueryResponse lastResponse
) throws WaitStrategyExhaustedException {
try {
return waitStrategy == null ? null : waitStrategy.getWait();
} catch (WaitStrategyExhaustedException e) {
if (lastResponse == null) {
// We'll try once anyway
return "0ms";
} else {
throw new WaitStrategyExhaustedException(e.getMessage() + ", last response: " + lastResponse, e);
}
}
}
private ServerQueryResponse executeServerQueryRaw(
@Nullable final QueryOptions options,
@Nullable final String wait,
final ValueExtractor valueExtractor,
RequestBuilder requestBuilder
) throws IOException, NomadException {
String region = apiClient.getConfig().getRegion();
String namespace = apiClient.getConfig().getNamespace();
String authToken = apiClient.getConfig().getAuthToken();
if (options != null) {
if (options.getRegion() != null)
region = options.getRegion();
if (options.getNamespace() != null)
namespace = options.getNamespace();
if (options.getAuthToken() != null)
authToken = options.getAuthToken();
if (options.getIndex() != null)
requestBuilder.addParameter("index", options.getIndex().toString());
if (wait != null)
requestBuilder.addParameter("wait", wait);
if (options.isAllowStale())
requestBuilder.addParameter("stale", null);
}
if (region != null)
requestBuilder.addParameter("region", region);
if (namespace != null)
requestBuilder.addParameter("namespace", namespace);
if (authToken != null)
requestBuilder.addHeader("X-Nomad-Token", authToken);
return apiClient.execute(requestBuilder, new ServerQueryResponseAdapter<>(valueExtractor));
}
private RequestBuilder prepareWrite(
final RequestBuilder builder,
final URIBuilder uri,
@Nullable final WriteOptions options
) {
String region = apiClient.getConfig().getRegion();
String namespace = apiClient.getConfig().getNamespace();
String secretId = apiClient.getConfig().getAuthToken();
if (options != null) {
if (options.getRegion() != null)
region = options.getRegion();
if (options.getNamespace() != null)
namespace = options.getNamespace();
if (options.getSecretId() != null)
secretId = options.getSecretId();
}
if (region != null)
uri.addParameter("region", region);
if (namespace != null)
uri.addParameter("namespace", namespace);
if (secretId != null)
builder.addHeader("X-Nomad-Token", secretId);
return builder.setUri(build(uri));
}
/**
* Builds a @{link NomadResponse} from an HTTP response.
*
* @param type that is extracted from the response body
*/
private static class NomadResponseAdapter extends ResponseAdapter> {
NomadResponseAdapter(final ValueExtractor valueExtractor) {
super(valueExtractor);
}
@Override
protected NomadResponse buildResponse(
final HttpResponse httpResponse,
final String rawEntity,
@Nullable final T value
) {
return new NomadResponse<>(rawEntity, value);
}
}
/**
* Builds a @{link ServerResponse} from an HTTP response.
*
* @param type that is extracted from the response body
*/
private static class ServerResponseAdapter extends ResponseAdapter> {
ServerResponseAdapter(@Nullable final ValueExtractor valueExtractor) {
super(valueExtractor);
}
@Override
protected ServerResponse buildResponse(
final HttpResponse httpResponse,
final String rawEntity,
@Nullable final T value
) {
return new ServerResponse<>(httpResponse, rawEntity, value);
}
}
/**
* Builds a @{link ServerQueryResponse} from an HTTP response.
*
* @param type that is extracted from the response body
*/
private static class ServerQueryResponseAdapter extends ResponseAdapter> {
ServerQueryResponseAdapter(@Nullable final ValueExtractor valueExtractor) {
super(valueExtractor);
}
@Override
protected ServerQueryResponse buildResponse(
final HttpResponse httpResponse,
final String rawEntity,
@Nullable final T value
) {
return new ServerQueryResponse<>(httpResponse, rawEntity, value);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy